Reputation: 41
I need to find the intersection point of two data sets, as illustrated here:
I have used the nested loops below to achieve this, but it takes impractically long to run for a dataframe with more (~1000) rows. How can I do this more efficiently?
For clarity, here is a screenshot of the CSV used in the example (len=20):
import pandas as pd
data = pd.read_csv("Less_Data.csv")
#Intersection of line A (points 1 & 2) and line B (points 3 & 4)
def findIntersection(x1,y1,x2,y2,x3,y3,x4,y4):
px= (( (x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4) )
/ ( (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4) ))
py= (( (x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4) )
/ ( (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4) ))
return [px, py]
#Find intersection of two series
intersections = {}
error_x = {}
error_y = {}
count = 0
print('All intersections found:')
for i in range(len(data)):
i_storage_modulus = data.iloc[i]['Storage_Modulus_Pa']
i_storage_stress = data.iloc[i]['Storage_Oscillation_Stress_Pa']
for j in range(len(data)):
j_storage_modulus = data.iloc[j]['Storage_Modulus_Pa']
j_storage_stress = data.iloc[j]['Storage_Oscillation_Stress_Pa']
if i == j + 1:
for k in range(len(data)):
k_loss_stress = data.iloc[k]['Loss_Oscillation_Stress_Pa']
k_loss_modulus = data.iloc[k]['Loss_Modulus_Pa']
for l in range(len(data)):
l_loss_stress = data.iloc[l]['Loss_Oscillation_Stress_Pa']
l_loss_modulus = data.iloc[l]['Loss_Modulus_Pa']
if k == l + 1:
if (max(k_loss_modulus, l_loss_modulus)
<= min(i_storage_modulus, j_storage_modulus)):
continue
else:
sample_intersect = findIntersection(i_storage_stress,
i_storage_modulus,
j_storage_stress,
j_storage_modulus,
k_loss_stress,
k_loss_modulus,
l_loss_stress,
l_loss_modulus)
if (min(i_storage_stress, j_storage_stress)
<= sample_intersect[0]
<= max(i_storage_stress, j_storage_stress)):
if (min(k_loss_stress, l_loss_stress)
<= sample_intersect[0]
<= max(k_loss_stress, l_loss_stress)):
print(sample_intersect)
intersections[count] = sample_intersect
error_x[count] = ([i_storage_stress,
j_storage_stress,
k_loss_stress,
l_loss_stress])
error_y[count] = ([i_storage_modulus,
j_storage_modulus,
k_loss_modulus,
l_loss_modulus])
count += 1
#Determine error bars
min_x_poss = []
max_x_poss = []
for i in error_x[0]:
if i < intersections[0][0]:
min_x_poss.append(i)
if i > intersections[0][0]:
max_x_poss.append(i)
x_error = (min(max_x_poss) - max(min_x_poss)) / 2
min_y_poss = []
max_y_poss = []
for i in error_y[0]:
if i < intersections[0][1]:
min_y_poss.append(i)
if i > intersections[0][1]:
max_y_poss.append(i)
y_error = (min(max_y_poss) - max(min_y_poss)) / 2
#Print results
print('\n', 'Yield Stress: ' + str(int(intersections[0][0])) + ' ± ' +
str(int(x_error)) + ' Pa (' +
str(int(x_error*100/intersections[0][0]))+'%)')
print('\n', 'Yield Modulus: ' + str(int(intersections[0][1])) + ' ± ' +
str(int(y_error)) + ' Pa (' +
str(int(y_error*100/intersections[0][1]))+'%)')
Upvotes: 0
Views: 771
Reputation: 3001
Can you create a new function y = (Storage Modulus - Loss Modulus) vs Oscillation Stress
? The point of intersection is where y
changes sign from positive to negative. The secant method should find this point in a few iterations.
https://en.wikipedia.org/wiki/Secant_method
Upvotes: 1