繁体   English   中英

Pandas 数据框:将函数应用于前一行的行值和值

[英]Pandas dataframe : Applying function to row value and value from the previous row

我正在尝试将以下函数应用于 Pandas 数据框:

def eukarney(lat1, lon1, alt1, lat2, lon2, alt2):
    p1 = (lat1, lon1)
    p2 = (lat2, lon2)
    karney = distance.distance(p1, p2).m
    return np.sqrt(karney**2 + (alt2 - alt1)**2)

如果我使用离散值,例如:

distance = eukarney(49.907611, 5.890404, 339.15734, 49.907683, 5.890373, 339.18224)

但是,如果我尝试将该函数应用于 Pandas 数据帧:

df['distances'] = eukarney(df['latitude'], df['longitude'], df['altitude'], df['latitude'].shift(), df['longitude'].shift(), df['altitude'].shift())

这意味着从一行和前一行中获取值。

我收到以下错误消息:

回溯(最近一次通话):文件“/home/mirix/Desktop/plage/GPX_invert_sense_change_starting_point_va.py”,第 78 行,在 df['distances'] = eukarney(df.loc[:,'latitude':], df .loc[:,'longitude':], df.loc[:,'altitude':], df.loc[:,'latitude':].shift(), df.loc[:,'longitude':] .shift(), df.loc[:,'altitude':].shift()) 文件“/home/mirix/Desktop/plage/GPX_invert_sense_change_starting_point_va.py”,第75行,在eukarney karney = distance.distance(p1, p2).m 文件“/home/mirix/.local/lib/python3.9/site-packages/geopy/distance.py”,第 522 行,在init super() 中。 init (*args, **kwargs) File "/home/mirix/.local/lib/python3.9/site-packages/geopy/distance.py", line 276, in init km += self.measure(a, b) 文件“/home/mirix/.local/lib/python3.9/site-packages/geopy/distance.py”,第 538 行,测量 a,b = Point(a), Point(b) 文件“/ home/mirix/.local/lib/python3.9/site-packages/geopy/point.py”,第 175 行,在新的返回 cls.from_sequence(seq) 文件“/home/mirix/.local/lib/python3. 9/site-packages/geopy/point.py”,第 472 行,在 from_sequence 中返回 cls(*args) 文件“/home/mirix/.local/lib/python3.9/site-packages/geopy/point.py” ,第 188 行,在新的_normalize_coordinates(纬度,经度,海拔)文件“/home/mirix/.local/lib/python3.9/site-packages/geopy/point.py”中,第 57 行,在 _normalize_coordinates latitude = float(纬度或 0.0)文件“/home/mirix/.local/lib/python3.9/site-packages/pandas/core/generic.py”,第 1534 行,非零引发 ValueError(ValueError:DataFrame 的真值是模棱两可。使用 a.empty、a.bool()、a.item()、a.any() 或 a。 全部()。

有趣的是,相同的语法适用于不使用 geopy 库的其他函数。

有任何想法吗?

解决方案

GeoPy 的距离函数似乎有一个内在的限制,它似乎只接受标量。

以下解决方法基于@SeaBen 回答如下:

df['lat_shift'] = df['latitude'].shift().fillna(df['latitude'])
df['lon_shift'] = df['longitude'].shift().fillna(df['longitude'])
df['alt_shift'] = df['altitude'].shift().fillna(df['altitude'])

df['distances'] = df.apply(lambda x: eukarney(x['latitude'], x['longitude'], x['altitude'], x['lat_shift'], x['lon_shift'], x['alt_shift']), axis=1).fillna(0)

您可以在每一行上使用.apply() ,如下所示:

在这里, .apply()帮助您将标量值逐行传递给自定义函数。 因此,使您能够重用设计用于处理标量值的自定义函数。 否则,您可能需要修改自定义函数以支持 Pandas 的矢量化数组值。

为了迎合.shift()条目,一种解决方法是首先为它们定义新列,以便我们可以将它们传递给.apply()函数。

# Take previous entry by shift and `fillna` with original value for first row entry 
# (for in case the custom function cannot handle `NaN` entry on first row after shift)
df['lat_shift'] = df['latitude'].shift().fillna(df['latitude'])
df['lon_shift'] = df['longitude'].shift().fillna(df['longitude'])
df['alt_shift'] = df['altitude'].shift().fillna(df['altitude'])

df['distances'] = df.apply(lambda x: eukarney(x['latitude'], x['longitude'], x['altitude'], x['lat_shift'], x['lon_shift'], x['alt_shift']), axis=1).fillna(0)

暂无
暂无

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

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