我有一个这样的数据框:
df = pd.DataFrame({
'A': ['a', 'a', 'a', 'a', 'a'],
'lon1': [128.0, 135.0, 125.0, 123.0, 136.0],
'lon2': [128.0, 135.0, 139.0, 142.0, 121.0],
'lat1': [38.0, 32.0, 38.0, 38.0, 38.0],
'lat2': [31.0, 32.0, 35.0, 38.0, 29.0],
'angle': [0, 0, 0, 0, 0]
})
我想通过此函数计算每一行的角度并保存回角度列
def angle(lon1,lat1,lon2,lat2):
dx = lon2 - lon1
dy = lat2 - lat1
direction = 0;
if ((dx == 0) & (dy == 0)): # same position
return direction
if (dx > 0.0) :
direction = 90-np.arctan2(dy,dx)*180/np.pi
elif (dy > 0.0 ) :
direction = 180+(270-(np.arctan2(dy,dx)*180/np.pi))
else :
direction = 360-(270+(np.arctan2(dy,dx)*180/np.pi))
if (direction < 0) :
direction += 360
return (direction.astype(int) % 360)
我试过
df.ix[df['A'].notnull(), 'angle'] =angle(
df[df['A'].notnull()]['lon1'],
df[df['A'].notnull()]['lat1'],
df[df['A'].notnull()]['lon2'],
df[df['A'].notnull()]['lat2'])
我收到了错误
ValueError:系列的真值是不明确的。使用a.empty,a.bool(),a.item(),a.any()或a.all()。
我试过for index,row in df.iterrows():
for循环的结果还可以,但是花了很长时间(原始数据大约是1000万行)
有人可以提供一些有效的方法吗?
答案 0 :(得分:1)
您似乎正在尝试将函数angle(...)
应用于数据框的每一行。
首先,有必要将所有字符串类型的数字转换为float,以便计算。
df1.loc[:, "lon1"] = df1.loc[:, "lon1"].astype("float")
df1.loc[:, "lon2"] = df1.loc[:, "lon2"].astype("float")
df1.loc[:, "lat1"] = df1.loc[:, "lat2"].astype("float")
df1.loc[:, "lat2"] = df1.loc[:, "lat2"].astype("float")
你去。
df1.loc[:, "angle"] = df1.apply(lambda x: angle(x["lon1"], x["lat1"], x["lon2"], x["lat2"]), axis = 1)
至于性能问题,这里有一些提示。
numba
进行JIT编译和函数的自动矢量化。答案 1 :(得分:0)
我确定这是一个更具矢量化的解决方案,但这是一个使用apply
方法的行方式版本的解决方案,它只会略微改变您的功能:
def angle(row):
dx = row.lon2 - row.lon1
dy = row.lat2 - row.lat1
direction = 0;
if ((dx == 0) & (dy == 0)): # same position
return direction
if (dx > 0.0) :
direction = 90-np.arctan2(dy,dx)*180/np.pi
elif (dy > 0.0 ) :
direction = 180+(270-(np.arctan2(dy,dx)*180/np.pi))
else :
direction = 360-(270+(np.arctan2(dy,dx)*180/np.pi))
if (direction < 0) :
direction += 360
return (direction.astype(int) % 360)
df['angle'] = df.apply(angle, axis=1)
输出:
A angle lat1 lat2 lon1 lon2
0 a 180 38.0 31.0 128.0 128.0
1 a 0 32.0 32.0 135.0 135.0
2 a 102 38.0 35.0 125.0 139.0
3 a 90 38.0 38.0 123.0 142.0
4 a 239 38.0 29.0 136.0 121.0