我试图插入列表中的角度。
Dir DirOffset
0 109.6085
30 77.5099
60 30.5287
90 -10.2748
120 -75.359
150 -147.6015
180 -162.7055
210 21.0103
240 3.5502
270 -11.5475
300 -39.8371
330 -109.5473
360 109.6085
我已经编写了插入角度的代码(它继续计算角度之间的平均值以达到插值),这需要很长时间。如果有人有更快更短的代码,请帮助我。
from cmath import rect, phase
from math import radians, degrees, sqrt
#Calculate the mean of angles in List
def mean_angle(degArray):
return degrees(phase(sum(rect(1, radians(d)) for d in degArray)/len(degArray)))
#Calculate Interpolation Angle
def Interpolate_angle(Dir, DirOffset, ValuetoInterpolate):
#Create Lower and Higher bin of ValuetoInterpolate
DirLBin = round(float(ValuetoInterpolate)/30,0)*30
DirHBin = round(float(ValuetoInterpolate+15)/30,0)*30
#Check if the ValuetoInterpolate lies between Lower and Higher bin
if DirLBin == DirHBin:
DirLBin = DirHBin-30
if DirLBin <= ValuetoInterpolate <= DirHBin:
DBin = [float(DirLBin), float(DirHBin)]
Doff = [DirOffset[Dir.index(DirLBin)], DirOffset[Dir.index(DirHBin)]]
else:
DirHBin = DirLBin+30
DBin = [float(DirLBin), float(DirHBin)]
Doff = [DirOffset[Dir.index(DirLBin)], DirOffset[Dir.index(DirHBin)]]
else:
DBin = [float(DirLBin), float(DirHBin)]
Doff = [DirOffset[Dir.index(DirLBin)], DirOffset[Dir.index(DirHBin)]]
#Run 50 iterations to calculate the mean of angle and find the ValuetoInterpolate
for i in range(51):
DMean = mean_angle(DBin)
DOMean = mean_angle(Doff)
if DMean < 0 :
DMean = 360+DMean
if DBin[0] <= ValuetoInterpolate <=DMean:
DBin = [float(DBin[0]), float(DMean)]
Doff = [float(Doff[0]), float(DOMean)]
else:
DBin = [float(DMean), float(DBin[1])]
Doff = [float(DOMean), float(Doff[1])]
return DOMean
Dir = range(0,370,30)
DirOffset = [109.6085,77.5099,30.5287,-10.2748,-75.359,-147.6015,-162.7055,21.0103,3.5502,-11.5475,-39.8371,-109.5473,109.6085]
ValuetoInterpolate = 194.4
print Interpolate_angle(Dir, DirOffset, ValuetoInterpolate)
答案 0 :(得分:2)
在从stackoverflow中搜索答案后,我得到了上述问题的解决方案,然后我根据我的要求进行了一点修改以获得解决方案。该解决方案可能对某些需要它的人有用。
我使用以下函数为每个方向bin(0,30,60 .... 360)插入度数直到360(360和0度将相同)并将它们存储在字典中以创建DataFrame(pandas DataFrame)并将其与主DataFrame连接并进一步处理。
def InterpolateDegrees(109.6085,77.5099)
将返回DirectionOffset的插值数组0到30度,间隔为0.1(0.0,0.1,0.2,0.3 ...... 28.7,29.8,29.9)
import numpy as np
from math import fabs
def InterpolateDegrees(start, end, BinSector=12):
BinAngle = 360/BinSector
amount = np.arange(0,1,(1/(BinAngle/0.1)))
dif = fabs(end-start)
if dif >180:
if end>start:
start+=360
else:
end+=360
#Interpolate it
value = (start + ((end-start)*amount))
#Wrap it
rzero = 360
Arr = np.where((value>=0) & (value<=360), (value), (value % rzero))
return Arr
答案 1 :(得分:1)
这是一个基于 Pandas/Numpy 的解决方案,用于使用 NaN 数据对角度序列进行插值。
import pandas as pd
import numpy as np
def interpolate_degrees(series: pd.Series) -> pd.Series:
# I don't want to modify in place
series = series.copy()
# convert to radians
a = np.radians(series)
# unwrap if not nan
a[~np.isnan(a)] = np.unwrap(a[~np.isnan(a)])
series.update(a)
# interpolate unwrapped values
interpolated = series.interpolate()
# wrap 0 - 360 (2*pi)
wrapped = (interpolated + 2*np.pi) % (2 * np.pi)
# cconvert back to degrees
degrees = np.degrees(wrapped)
series.update(degrees)
return series
用法:
angle = [350, np.nan, 355, np.nan, 359, np.nan, 1, np.nan, 10]
df = pd.DataFrame(data=angle, columns=['angle'])
df['interpolated'] = interpolate_degrees(df.angle)