将 Pandas 函数应用于多个列

3
我有一个函数,其中我设置了返回两个值(称为Site和Date)。我正在尝试使用df.apply创建两个新列,每个列代表一个返回的值。我不想多次应用此函数,因为这将需要很长时间,所以我需要一种方式将两个列的值设置为函数中的两个或多个值。以下是我的代码。
df1[['Site','Site Date']] = df1.apply(
    lambda row: firstSite(biomass, row['lat'], row['long'], row['Date']), 
    axis = 1)

输入值生物量是一个数据帧,其中行“lat”,“lng”,“Date”都是来自df1的列。如果我决定将此函数应用于df ['Site'],它可以完美地工作,但当我想要将值应用于两个列时,就会出现此错误。

ValueError: Shape of passed values is (999, 2), indices imply (999, 28)

def firstSite(biomass, lat, long, date):

    biomass['Date of Operation']  = pd.to_datetime(biomass['Date of Operation'])
    biomass = biomass[biomass['Date of Operation'] <= date]

    biomass['distance'] = biomass.apply(
        lambda row: distanceBetweenCm(lat, long, row['Lat'], row['Lng']), 
        axis=1)
    biomass['Site Name'] = np.where((biomass['distance'] <= 2), biomass['Site Name'], "Null")
    biomass = biomass.drop_duplicates('Site Name')
    Site = biomass.loc[biomass['Date of Operation'].idxmin(),'Site Name']
    Lat = biomass.loc[biomass['Date of Operation'].idxmin(),'Lat']
    return Site, Lat

这个函数有几个任务:

1 - 它会删除生物量数据中日期在df1['Date']之后的任何行。

2 - 如果坐标之间的距离大于2,'Site Name'的值将被更改为'Null'。

3 - 它将从站点名称中删除重复项,并确保只有一个值为'Null'的行。

4 - 它返回'Date of Operation'最早的'Site Name'和'Lat'的值。

我需要我的代码返回距离df1和生物量之间坐标距离小于2公里的第一条记录。

希望能够返回许多不同半径内的第一条记录,例如2公里、4公里、6公里、8公里、10公里内的第一个生物量站点。


如果 df2 = df1.apply(lambda row: firstSite(biomass, row['lat'], row['long'], row['Date']), axis=1),那么 print(df2.info()) 是什么意思? - jezrael
AttributeError: 'Series' 对象没有 'info' 属性。 - christaylor
好的,输出是Series,那么为什么要将输出添加到2列中呢?当输出是Series(在df中的列)时,为什么要这样做df1[['Site','Site Date']] - jezrael
我认为你能否再解释一下? - jezrael
哦,那我该怎么把这些Series添加到df1中呢?给我一分钟,我会编辑我的帖子并附上函数“firstSite”。 - christaylor
也许可以使用一个临时变量来存储从函数返回的元组/列表。然后将它们拆分开来,例如 df['Site'] = tmp[0] - jf328
1个回答

5
我认为您的函数需要返回一个带有2个值的Series:
df1 = pd.DataFrame({'A':list('abcdef'),
                   'lat':[4,5,4,5,5,4],
                   'long':[7,8,9,4,2,3],
                   'Date':pd.date_range('2011-01-01', periods=6),
                   'E':[5,3,6,9,2,4],
                   'F':list('aaabbb')})

print (df1)
   A       Date  E  F  lat  long
0  a 2011-01-01  5  a    4     7
1  b 2011-01-02  3  a    5     8
2  c 2011-01-03  6  a    4     9
3  d 2011-01-04  9  b    5     4
4  e 2011-01-05  2  b    5     2
5  f 2011-01-06  4  b    4     3

biomass = 10
def firstSite(a,b,c,d):
    return pd.Series([a + b, d])

df1[['Site','Site Date']] = df1.apply(lambda row: firstSite(biomass,
                                                  row['lat'], row['long'], row['Date']), 
                                                  axis = 1)
print (df1)
   A       Date  E  F  lat  long  Site  Site Date
0  a 2011-01-01  5  a    4     7    14 2011-01-01
1  b 2011-01-02  3  a    5     8    15 2011-01-02
2  c 2011-01-03  6  a    4     9    14 2011-01-03
3  d 2011-01-04  9  b    5     4    15 2011-01-04
4  e 2011-01-05  2  b    5     2    15 2011-01-05
5  f 2011-01-06  4  b    4     3    14 2011-01-06

很高兴能够帮到您。请不要忘记点赞并接受解决方案。谢谢。 - jezrael
哦,抱歉,已经完成了。我还是比较新手的StackOverflow用户,所以有时会忘记! - christaylor
没问题,谢谢。 - jezrael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接