考虑数据框df
df = pd.DataFrame(dict(
A=list('xxxyyy'),
B=[np.nan, 1, 2, 3, 4, np.nan]
))
df
A B
0 x NaN
1 x 1.0
2 x 2.0
3 y 3.0
4 y 4.0
5 y NaN
我可以使用agg
中的函数并传递像这样的参数
df.groupby('A').B.agg(pd.Series.head, n=1)
A
x NaN
y 3.0
Name: B, dtype: float64
但是,我想使用pd.Series.head
和pd.Series.tail
运行聚合。我想将论据n=1
传递给他们两个。
我希望这个聚合看起来像下面的结果。重要的是要注意我已经可以产生这个结果。我的目标是弄清楚如何将参数传递给传递给agg
的多个函数。
如果无法做到,解释为什么这是一个有效的答案。
h t
A
x NaN 2.0
y 3.0 NaN
添加奖励
如果你想出来......这将是一个比我this question更好的解决方案。我会鼓励任何回答这个问题的人也回答那个问题。
答案 0 :(得分:3)
如果我理解正确the source code,则无法完成:
def aggregate(self, func_or_funcs, *args, **kwargs):
_level = kwargs.pop('_level', None)
if isinstance(func_or_funcs, compat.string_types):
return getattr(self, func_or_funcs)(*args, **kwargs) # NOTE: (*args, **kwargs) are passed to the function
if hasattr(func_or_funcs, '__iter__'):
ret = self._aggregate_multiple_funcs(func_or_funcs, # NOTE: `*args, **kwargs` got lost ...
(_level or 0) + 1)
...
注意:如果func_or_funcs
'__iter__'
属性*args
,**kwargs
将被忽略......
答案 1 :(得分:2)
您可以将字典中的lambdas传递给agg
>> df.groupby('A').B.agg({'h': lambda s: s.head(1), 't': lambda s: s.tail(1)})
但你可能不会在将来通过它
FutureWarning:不推荐在系列上使用dict进行聚合 并将在以后的版本中删除
我更喜欢重命名lambdas并阻止
SpecificationError:函数名必须唯一,找到多个 命名
>> h = lambda s: s.head(1)
>> h.__name__ = 'h'
>> t = lambda s: s.tail(1)
>> t.__name__ = 't'
>> df.groupby('A').B.agg([h, t])
>>
>> h t
>> A
>> x NaN 2.0
>> y 3.0 NaN
看起来5行太多,但线条很短!
将其他kwargs传递给agg函数的一种可能的解决方法是使用partial
>> from functools import partial
>> df.groupby('A').B.agg([partial(pd.Series.head, n=1),
>> partial(pd.Series.tail, n=1)])
>>
>> head tail
>> A
>> x NaN 2.0
>> y 3.0 NaN