【问题标题】:Pandas - Create column using itertuplesPandas - 使用 itertuples 创建列
【发布时间】:2017-11-19 12:01:40
【问题描述】:

我有一个pandas.DataFrameAcctIdLatitudeLongitude。我也有一个坐标列表。我正在尝试计算纬度和经度与列表中每个坐标对之间的距离(使用半正弦公式)。然后我想返回最小距离,并在数据框中创建一个带有值的新列。

但是,我的输出表只返回循环中最后一行的距离值。我尝试过使用itertuplesiterrows 和普通循环,但这些方法都不适合我。

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)

【问题讨论】:

    标签: python list loops pandas itertools


    【解决方案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) 可以在候选人附近找到。将真正取决于您的数据的性质。
    猜你喜欢
    • 2017-08-30
    • 2017-03-25
    • 1970-01-01
    • 2021-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    相关资源
    最近更新 更多