Python Groupby并应用已定义的函数-Pandas

Python Groupby并应用已定义的函数-Pandas,python,pandas,dataframe,Python,Pandas,Dataframe,我有这个df: ID Date Time Lat Lon Time_1 Lat_1 Lon_1 A 07/16/2019 08:00 29.39291 -98.50925 09:00 29.39923 -98.51256 A 07/16/2019 09:00 29.39923 -98.51256 10:00 29.40147 -98.51123 A 07/16/2019 10:00 29.40147

我有这个df:

ID         Date   Time       Lat       Lon Time_1     Lat_1     Lon_1
 A  07/16/2019   08:00  29.39291 -98.50925  09:00  29.39923 -98.51256
 A  07/16/2019   09:00  29.39923 -98.51256  10:00  29.40147 -98.51123
 A  07/16/2019   10:00  29.40147 -98.51123  10:00  29.40147 -98.51123
 A  07/18/2019   08:30  29.38752 -98.52372  09:30  29.39291 -98.50925
 A  07/18/2019   09:30  29.39291 -98.50925  09:30  29.39291 -98.50925
 B  07/16/2019   08:00  29.39537 -98.50402  08:00  29.39537 -98.50402
 B  07/18/2019   11:00  29.39343 -98.49707  12:00  29.39291 -98.50925
 B  07/18/2019   12:00  29.39291 -98.50925  12:00  29.39291 -98.50925
 B  07/19/2019   10:00  29.39556 -98.53148  10:00  29.39556 -98.53148
我想通过按
ID
Date
对df进行分组来创建
“Distance”
列,并应用已定义的函数

我写的代码是:

def grp_crossarc(f):

    for i in range(len(f)):

        f.loc[i,'Distance'] = crossarc(f.iloc[i]['Lat'],f.iloc[i]['Lon'],
                                         f.iloc[i]['Lat_1'],f.iloc[i]['Lat_1'],
                                         29.39537,-98.50402)
    return f

df.groupby(['ID','Date'],as_index=False).apply(grp_crossarc)
crossarc
是另一个定义的函数,它获取6个参数(3个纬度点)

我得到的结果是:

  ID         Date   Time       Lat       Lon Time_1     Lat_1     Lon_1  Distance
   A  07/16/2019   08:00  29.39291 -98.50925  09:00  29.39923 -98.51256  0.166057
   A  07/16/2019   09:00  29.39923 -98.51256  10:00  29.40147 -98.51123  0.889147
   A  07/16/2019   10:00  29.40147 -98.51123  10:00  29.40147 -98.51123  0.973550
   A  07/18/2019   08:30  29.38752 -98.52372  09:30  29.39291 -98.50925       NaN
   A  07/18/2019   09:30  29.39291 -98.50925  09:30  29.39291 -98.50925       NaN
 NaN          NaN    NaN       NaN       NaN    NaN       NaN       NaN  0.736501
 NaN          NaN    NaN       NaN       NaN    NaN       NaN       NaN  0.165974
   B  07/16/2019   08:00  29.39537 -98.50402  08:00  29.39537 -98.50402       NaN
 NaN          NaN    NaN       NaN       NaN    NaN       NaN       NaN  0.000000
   B  07/18/2019   11:00  29.39343 -98.49707  12:00  29.39291 -98.50925       NaN
   B  07/18/2019   12:00  29.39291 -98.50925  12:00  29.39291 -98.50925       NaN
 NaN          NaN    NaN       NaN       NaN    NaN       NaN       NaN  0.707027
 NaN          NaN    NaN       NaN       NaN    NaN       NaN       NaN  0.165974
   B  07/19/2019   10:00  29.39556 -98.53148  10:00  29.39556 -98.53148       NaN
 NaN          NaN    NaN       NaN       NaN    NaN       NaN       NaN  1.900238

对于少数
(ID,Date)
对,距离值向前移动了一行,因此创建了NaN值。如何修复它?

您可以尝试lambda函数,而不是循环:

def grp_crossarc(f):
    f['Distance'] = (f.apply(lambda x: crossarc(x['Lat'],x['Lon'],
                                                x['Lat_1'],x['Lat_1'],
                                                29.39537,-98.50402), axis=1))
    return f

df = df.groupby(['ID','Date'],as_index=False).apply(grp_crossarc)
但函数似乎不依赖于组,因此应该使用省略
groupby.apply来简化:

df['Distance'] = (df.apply(lambda x: crossarc(x['Lat'],x['Lon'],
                                              x['Lat_1'],x['Lat_1'],
                                              29.39537,-98.50402), axis=1))

也许这有助于
df['col_3']=df.apply(lambda x:f(x.col_1,x.col_2,axis=1)
其中
f
是用户定义的函数是的,你是对的。该功能不依赖于组。非常感谢。顺便问一下,您有解决方案吗(没有定义函数):?@qwerty-我尝试了一下,这是第一次看到可能,但更好的测试。@qwerty-我添加了3个解决方案;)