Pandas - 使用 itertuples 创建列
Posted
技术标签:
【中文标题】Pandas - 使用 itertuples 创建列【英文标题】:Pandas - Create column using itertuples 【发布时间】:2017-11-19 12:01:40 【问题描述】:我有一个pandas.DataFrame
和AcctId
、Latitude
和Longitude
。我也有一个坐标列表。我正在尝试计算纬度和经度与列表中每个坐标对之间的距离(使用半正弦公式)。然后我想返回最小距离,并在数据框中创建一个带有值的新列。
但是,我的输出表只返回循环中最后一行的距离值。我尝试过使用itertuples
、iterrows
和普通循环,但这些方法都不适合我。
df
AcctId Latitude Longitude
123 40.50 -90.13
123 40.53 -90.21
123 40.56 -90.45
123 40.63 -91.34
coords = [41.45,-95.13,39.53,-100.42,45.53,-95.32]
for row in df.itertuples():
Latitude = row[1]
Longitude = row[2]
distances = []
lat = []
lng = []
for i in xrange(0, len(coords),2):
distances.append(haversine_formula(Latitude,coords[i],Longitude,coords[i+1])
lat.append(coords[i])
lng.append(coords[i+1])
min_distance = min(distances)
df['Output'] = min_distance
期望的输出:
df
AcctId Latitude Longitude Output
123 40.50 -90.13 23.21
123 40.53 -90.21 38.42
123 40.56 -90.45 41.49
123 40.63 -91.34 42.45
实际输出:
df
AcctId Latitude Longitude Output
123 40.50 -90.13 42.45
123 40.53 -90.21 42.45
123 40.56 -90.45 42.45
123 40.63 -91.34 42.45
最终代码
for row in df.itertuples():
def min_distance(row):
here = (row.Latitude, row.Longitude)
return min(haversine(here, coord) for coord in coords)
df['Nearest_Distance'] = df.apply(min_distance, axis=1)
【问题讨论】:
【参考方案1】:您正在寻找pandas.DataFrame.apply()
。比如:
代码:
df['output'] = df.apply(min_distance, axis=1)
测试代码:
df = pd.read_fwf(StringIO(u'''
AcctId Latitude Longitude
123 40.50 -90.13
123 40.53 -90.21
123 40.56 -90.45
123 40.63 -91.34'''), header=1)
coords = [
(41.45, -95.13),
(39.53, -100.42),
(45.53, -95.32)
]
from haversine import haversine
def min_distance(row):
here = (row.Latitude, row.Longitude)
return min(haversine(here, coord) for coord in coords)
df['output'] = df.apply(min_distance, axis=1)
print(df)
结果:
AcctId Latitude Longitude output
0 123 40.50 -90.13 432.775598
1 123 40.53 -90.21 425.363959
2 123 40.56 -90.45 404.934516
3 123 40.63 -91.34 330.649766
【讨论】:
太棒了。我在这方面工作太久了。感谢您的帮助! 此解决方案有效,但在应用于大型数据帧(>2MM 行)时,df.apply
运行速度非常慢。对于df.apply
的替代方案有什么建议吗?
我敢打赌,主要缺乏速度是在haversine计算中。您应该分析代码。如果我是对的,您可能会考虑对距离进行估计,只需要对点的子集进行半正弦运算。
估计距离的好方法是什么?原谅我的无知——我对 Python 还很陌生。
好吧,如果您在某个纬度以下,您可以简单地使用sqrt(d_lat**2 + d_long**2)
进行初步近似,这样您就可以找到附近的东西。甚至更简单的是min(d_lat, d_long)
可以在候选人附近找到。将真正取决于您的数据的性质。以上是关于Pandas - 使用 itertuples 创建列的主要内容,如果未能解决你的问题,请参考以下文章
ValueError:在 Pandas 数据帧上使用 itertuples() 时解包的值太多
pandas遍历dataframe的行:迭代遍历dataframe的数据行iterrows函数itertuple函数
Pandas df.itertuples 在打印时重命名数据框列
pandas使用itertuples函数迭代dataframe中的数据行并自定义修改行中的数值(update row while iterating over the rows)