4

如果在 pandas 中编写要与 groupby.apply 或 groupby.transform 一起使用的函数,如果函数有多个参数,那么当作为 groupby 的一部分调用该函数时,参数后面是逗号而不是括号。一个例子是:

def Transfunc(df, arg1, arg2, arg2):
     return something

GroupedData.transform(Transfunc, arg1, arg2, arg3)

其中 df 参数作为第一个参数自动传递。

但是,在使用函数对数据进行分组时,似乎无法使用相同的语法。举个例子:

people = DataFrame(np.random.randn(5, 5), columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
people.ix[2:3, ['b', 'c']] = NA

def MeanPosition(Ind, df, Column):
    if df[Column][Ind] >= np.mean(df[Column]):
        return 'Greater Group'
    else:
        return 'Lesser Group'
# This function compares each data point in column 'a' to the mean of column 'a' and return a group name based on whether it is greater than or less than the mean

people.groupby(lambda x: MeanPosition(x, people, 'a')).mean()

上面的工作很好,但我不明白为什么我必须将函数包装在 lambda 中。根据与 transform 和 apply 一起使用的语法,在我看来,以下内容应该可以正常工作:

people.groupby(MeanPosition, people, 'a').mean()

谁能告诉我为什么,或者如何在不将其包装在 lambda 中的情况下调用该函数?

谢谢

编辑:我认为不可能通过将函数作为键传递而不将该函数包装在 lambda 中来对数据进行分组。一种可能的解决方法是传递一个由函数创建的数组,而不是将函数作为键传递。这将通过以下方式工作:

def MeanPositionList(df, Column):
    return ['Greater Group' if df[Column][row] >= np.mean(df[Column]) else 'Lesser Group' for row in df.index]

Grouped = people.groupby(np.array(MeanPositionList(people, 'a')))
Grouped.mean()

但是当然最好把中间人函数全部去掉,然后简单地使用一个带有列表理解的数组......

4

1 回答 1

2

将参数传递给apply恰好可以工作,因为apply将所有参数传递给目标函数。

但是,groupby需要多个参数,请参见此处,因此无法区分参数;传递一个 lambda / 命名函数更明确,也是要走的路。

这是我认为您想要的操作方法(稍作修改,因为您的示例中有所有不同的组)

In [22]: def f(x):
   ....:     result = Series('Greater',index=x.index)
   ....:     result[x<x.mean()] = 'Lesser'
   ....:     return result
   ....: 

In [25]: df = DataFrame(np.random.randn(5, 5), columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Joe', 'Wes', 'Wes', 'Travis'])

In [26]: df
Out[26]: 
               a         b         c         d         e
Joe    -0.293926  1.006531  0.289749 -0.186993 -0.009843
Joe    -0.228721 -0.071503  0.293486  1.126972 -0.808444
Wes     0.022887 -1.813960  1.195457  0.216040  0.287745
Wes    -1.520738 -0.303487  0.484829  1.644879  1.253210
Travis -0.061281 -0.517140  0.504645 -1.844633  0.683103

In [27]: df.groupby(df.index.values).transform(f)
Out[27]: 
              a        b        c        d        e
Joe      Lesser  Greater   Lesser   Lesser  Greater
Joe     Greater   Lesser  Greater  Greater   Lesser
Travis  Greater  Greater  Greater  Greater  Greater
Wes     Greater   Lesser  Greater   Lesser   Lesser
Wes      Lesser  Greater   Lesser  Greater  Greater
于 2013-11-04T12:47:51.587 回答