简体   繁体   English

计算角度的更有效方法?

[英]More efficient way to compute angles?

I have a dataframe with three points given as columns (so, a total of six):我有一个 dataframe 三个点作为列(所以,总共六个):

x_measured  y_measured  x_calculated  y_calculated  x_fixedpoint  \
0         142          37           143          37.5           138   
1         142          37           143          37.6           138   
2         142          37           143          37.7           138   
3         142          37           143          37.8           138   
4         142          37           143          37.9           138   
5          73          55            71          55.6            72   
6          73          55            71          55.7            72   
7          73          55            71          55.8            72   
8          73          55            71          55.9            72   
9          73          55            71          55.1            72   

   y_fixedpoint  
0            38  
1            38  
2            38  
3            38  
4            38  
5            55  
6            55  
7            55  
8            55  
9            55  

Now, I need to calculate the angle between (x_measured, y_measured) and (x_calculated y_calculated) relative to (x_fixedpoint, y_fixedpoint) .现在,我需要计算(x_measured, y_measured)(x_calculated y_calculated)之间相对于(x_fixedpoint, y_fixedpoint)的角度。 To do so, I created this function:为此,我创建了这个 function:

def angle_calculator(x1,x2,x3,x4,x5,x6):
    All_points = np.array([[x1,x2],[x3,x4],[x5,x6]])
    A = All_points[2] - All_points[0]
    B = All_points[1] - All_points[0]
    C = All_points[2] - All_points[1]

    for e1, e2 in ((A, B), (A, C), (B, -C)):
        dotproduct = np.dot(e1, e2)
        norm = np.linalg.norm(e1) * np.linalg.norm(e2)
        if dotproduct !=0:
            angle = round(np.arccos(dotproduct/norm) * 180 / np.pi, 2)
        else:
            angle = 0
    return angle

taking the different x,y coordinates as arguments and returning an angle.将不同的 x,y 坐标作为 arguments 并返回一个角度。 It works and gives:它有效并提供:

df['angles'] = df.apply(lambda x: angle_calculator(x.x_measured, x.y_measured, x.x_calculated, x.y_calculated, x.x_fixedpoint, x.y_fixedpoint), axis=1)

x_measured  y_measured  x_calculated  y_calculated  x_fixedpoint  \
0         142          37           143          37.5           138   
1         142          37           143          37.6           138   
2         142          37           143          37.7           138   
3         142          37           143          37.8           138   
4         142          37           143          37.9           138   
5          73          55            71          55.6            72   
6          73          55            71          55.7            72   
7          73          55            71          55.8            72   
8          73          55            71          55.9            72   
9          73          55            71          55.1            72   

   y_fixedpoint     angles  
0            38  32.275644  
1            38  35.537678  
2            38  38.425651  
3            38  40.950418  
4            38  43.132975  
5            55  14.264512  
6            55  15.701974  
7            55  16.858399  
8            55  17.759467  
9            55   2.848188 

Usually, I would be realatively pleased with this BUT.....it is rather slow for dataframes with over 200 000 rows.通常,我会对此感到非常满意,但是......对于超过 200 000 行的数据帧来说,它相当慢。 Slow (Iknow,) is a realtive term.慢(我知道,)是一个真实的术语。 but in this cas it takes around 10 seconds for 200 000 rows.但在这种情况下,200 000 行大约需要 10 秒。

So, my questions are:所以,我的问题是:

  1. Am I overcomplicating things?我是不是把事情复杂化了?
  2. Is there a more efficient way to do this?有没有更有效的方法来做到这一点?

As always, thankful for knowledge.一如既往,感谢知识。

Considering the values in the numpy domain, we can do:考虑到 numpy 域中的值,我们可以这样做:

# extract the pairs (and go to numpy)
meas = df.filter(like="measured").to_numpy()
calc = df.filter(like="calculated").to_numpy()
fix = df.filter(like="fixed").to_numpy()

# calculate the differences of `meas` and `calc` from `fix`
meas_dist = fix - meas
calc_dist = fix - calc

# get the inner products
inners = (meas_dist * calc_dist).sum(axis=1)
# or with: inners = np.einsum("ij,ij->i", meas_dist, calc_dist); might be faster

# norm function for brevity
norm = lambda mat: np.linalg.norm(mat, axis=1)

# get the angles (in radians)
angles_in_rad = np.arccos(inners / (norm(meas_dist) * norm(calc_dist)))

# handling possible NaNs (by @Serge de Gosson de Varennes, thanks!)
where_nans = isnan(angles_in_rad)
angles_in_rad[where_nans ] = 0

# go to degrees
angles_in_deg = np.rad2deg(angles_in_rad)

# put back to df
df["angles"] = angles_in_deg

I get:我得到:

>>> df

   x_measured  y_measured  x_calculated  y_calculated  x_fixedpoint  y_fixed_point      angles
0         142          37           143          37.5           138             38    8.325650
1         142          37           143          37.6           138             38    9.462322
2         142          37           143          37.7           138             38   10.602613
3         142          37           143          37.8           138             38   11.745633
4         142          37           143          37.9           138             38   12.890481
5          73          55            71          55.6            72             55  149.036243
6          73          55            71          55.7            72             55  145.007980
7          73          55            71          55.8            72             55  141.340192
8          73          55            71          55.9            72             55  138.012788
9          73          55            71          55.1            72             55  174.289407

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM