Issue
I want to create an array in which the values depends on one variables and two coefficients. The coefficient values depend on the variable value as well. A simple example:
x_intervals = [2, 10]
C1_values = [0.1, 0.5, -0.2]
C2_values = [0.4,0.6, -0.8]
Here I want C1 and C2:
- to be equal to the first array element if x<2 (so C1 = 0.1 and C2 = 0.4)
- to be equal to the second array element if x>2 and x>10 (so C1 = 0.5 and C2 = 0.6)
- to be equal to the third element if x>10 (so C1 = -0.2 and C2 = -0.8)
Then I want to use these coefficients to find the values of y=C1*x^C2 for any number of x contained in a list.
Currently I do this using subsequent if functions as:
x = [0.1,1,1.5,2.2,5,9,12,20,30,60,70,100]
y = []
for x_ in x:
if x_<=x_intervals[0]:
C1 = C1_values[0]
C2 = C2_values[0]
elif x_<=x_intervals[1]:
C1 = C1_values[1]
C2 = C2_values[1]
else:
C1 = C1_values[2]
C2 = C2_values[2]
y.append(C1*x_ **C2)
This works but it is extremely dirty and manual, and if I increase the number of intervals it becomes extremely long to code. I am sure that there is a smarter and cleaner way to do this.
Any idea? Thanks in advance
(Using Python, but this is more of a logic/algorithm question)
#################################################################### EDIT: Thank you all for your solutions. They all worked and are useful I found the numpy solution using searchsorted the most appropriate in my case. The code looks like this now (where Coeff_1 and Coeff_2 are two pandas dataframe where I store my coefficients C1 and C2):
def calculate_curve_value(Re=10, df=pd.DataFrame()):
MaxRe = df.loc["MaxRe"].values
C1 = df.loc["C1"].values
C2 = df.loc["C2"].values
idx = np.searchsorted(MaxRe, Re)
value = C1[idx]*Re**(C2[idx])
return value
Re = [0.1,1,1.5,2.2,5,9,12,20,30,60,70,100]
N = []
f = []
for i in Re:
N.append(calculate_curve_value(Re=i, df=Coeff_1))
f.append(calculate_curve_value(Re=i, df=Coeff_2))
Solution
It would make a lot of sense to use numpy here.
What you want is a searchsorted
on x_intervals
, then a vectorial operation:
import numpy as np
x_intervals = np.array([2, 10])
C1_values = np.array([0.1, 0.5, -0.2])
C2_values = np.array([0.4,0.6, -0.8])
x = [0.1,1,1.5,2.2,5,9,12,20,30,60,70,100]
idx = np.searchsorted(x_intervals, x)
y = C1_values[idx]*x**C2_values[idx]
Output:
array([ 0.03981072, 0.1 , 0.1176079 , 0.80246041, 1.3132639 ,
1.86859641, -0.02739586, -0.01820564, -0.01316234, -0.00755978,
-0.00668269, -0.00502377])
If you really want to use pure python, go with bisect
:
from bisect import bisect_left
x_intervals = [2, 10]
C1_values = [0.1, 0.5, -0.2]
C2_values = [0.4,0.6, -0.8]
x = [0.1,1,1.5,2.2,5,9,12,20,30,60,70,100]
y = []
for x_ in x:
idx = bisect_left(x_intervals, x_)
y.append(C1_values[idx]*x_**C2_values[idx])
Output:
[0.03981071705534973, 0.1, 0.11760790225246737, 0.8024604053351734, 1.3132639022018835, 1.8685964094232759, -0.027395863825287095, -0.0182056420302608, -0.013162336572232132, -0.007559777184220181, -0.006682693821222914, -0.005023772863019159]
Answered By - mozway
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.