该文档展示了如何使用输出列名称作为键的字典一次在groupby对象上应用多个功能:
In [563]: grouped['D'].agg({'result1' : np.sum,
.....: 'result2' : np.mean})
.....:
Out[563]:
result2 result1
A
bar -0.579846 -1.739537
foo -0.280588 -1.402938
但是,这仅适用于Series groupby对象。同样,当将字典类似地传递到groupby DataFrame时,它期望键是将应用该函数的列名。
我想做的是对多个列应用多个功能(但是某些列将被多次操作)。同样,某些函数将依赖于groupby对象中的其他列(如sumif函数)。我当前的解决方案是逐列进行操作,并使用类似于上面代码的代码,对依赖其他行的函数使用lambda。但这要花费很长时间,(我认为花很长时间来遍历groupby对象)。我必须对其进行更改,以便一次运行即可遍历整个groupby对象,但是我想知道熊猫中是否有内置的方法可以使此操作更加简洁。
例如,我尝试过类似
grouped.agg({'C_sum' : lambda x: x['C'].sum(),
'C_std': lambda x: x['C'].std(),
'D_sum' : lambda x: x['D'].sum()},
'D_sumifC3': lambda x: x['D'][x['C'] == 3].sum(), ...)
但正如我所料,我收到一个KeyError(因为如果agg从DataFrame调用,则键必须是一列)。
是否有任何内置方法可以执行我想做的事情,或者可能添加了此功能,或者我只需要手动遍历groupby?
当前接受的答案的后半部分已过时,并且有两个过时的建议。首先也是最重要的是,你不能再将字典词典传递给agggroupby
方法。第二,永远不要使用.ix
。
如果你希望同时使用两个单独的列,我建议使用apply
隐式将DataFrame
传递给应用函数的方法。让我们使用与上面类似的数据框
df = pd.DataFrame(np.random.rand(4,4), columns=list('abcd'))
df['group'] = [0, 0, 1, 1]
df
a b c d group
0 0.418500 0.030955 0.874869 0.145641 0
1 0.446069 0.901153 0.095052 0.487040 0
2 0.843026 0.936169 0.926090 0.041722 1
3 0.635846 0.439175 0.828787 0.714123 1
从列名映射到聚合函数的字典仍然是执行聚合的理想方法。
df.groupby('group').agg({'a':['sum', 'max'],
'b':'mean',
'c':'sum',
'd': lambda x: x.max() - x.min()})
a b c d
sum max mean sum <lambda>
group
0 0.864569 0.446069 0.466054 0.969921 0.341399
1 1.478872 0.843026 0.687672 1.754877 0.672401
如果你不喜欢该丑陋的lambda列名称,则可以使用常规函数,并为特殊__name__
属性提供自定义名称,如下所示:
def max_min(x):
return x.max() - x.min()
max_min.__name__ = 'Max minus Min'
df.groupby('group').agg({'a':['sum', 'max'],
'b':'mean',
'c':'sum',
'd': max_min})
a b c d
sum max mean sum Max minus Min
group
0 0.864569 0.446069 0.466054 0.969921 0.341399
1 1.478872 0.843026 0.687672 1.754877 0.672401
使用apply和返回系列
现在,如果有多个需要一起交互的列,则不能使用agg
,这会将Series
隐式传递给聚合函数。当apply
将整个组用作DataFrame
时,将传递给函数。
我建议创建一个自定义函数,以返回一系列所有聚合。使用系列索引作为新列的标签:
def f(x):
d = {}
d['a_sum'] = x['a'].sum()
d['a_max'] = x['a'].max()
d['b_mean'] = x['b'].mean()
d['c_d_prodsum'] = (x['c'] * x['d']).sum()
return pd.Series(d, index=['a_sum', 'a_max', 'b_mean', 'c_d_prodsum'])
df.groupby('group').apply(f)
a_sum a_max b_mean c_d_prodsum
group
0 0.864569 0.446069 0.466054 0.173711
1 1.478872 0.843026 0.687672 0.630494
如果你爱上了MultiIndexes,仍然可以返回带有以下内容的Series:
def f_mi(x):
d = []
d.append(x['a'].sum())
d.append(x['a'].max())
d.append(x['b'].mean())
d.append((x['c'] * x['d']).sum())
return pd.Series(d, index=[['a', 'a', 'b', 'c_d'],
['sum', 'max', 'mean', 'prodsum']])
df.groupby('group').apply(f_mi)
a b c_d
sum max mean prodsum
group
0 0.864569 0.446069 0.466054 0.173711
1 1.478872 0.843026 0.687672 0.630494
文档显示了如何使用以输出列名为键的dict一次对groupby对象应用多个函数: 但是,这只对Series groupby对象有效。并且当类似地将dict传递给groupby数据帧时,它希望键是将应用该函数的列名。 我想做的是对几个列应用多个函数(但某些列将被多次操作)。此外,一些函数将依赖于groupby对象中的其他列(如sumif函数)。我当前的解决方案是逐列执行,并执行与上面的代码类似的操作
问题内容: 在Python中,我们可以将函数分配给变量。例如,math.sine函数: 有没有简单的方法可以将多个函数(即一个函数的一个函数)分配给一个变量?例如: 问题答案: 我认为作者想要的是某种形式的功能链。通常,这很困难,但是对于 接受一个论点 返回一个值, 列表中上一个函数的返回值与列表中下一个函数的输入类型具有相同的返回值 我们说有一个需要链接的函数列表,其中有一个参数,然后返回一个参
问题内容: 如何将多个谓词应用于一个 方法? 这就是我现在要做的,但是我真的不喜欢它。我有一个东西,我需要根据过滤器(谓词)减少东西的数量: 我知道,如果我预先知道过滤器的数量,则可以执行以下操作: 但是如何在不混合编程样式的情况下应用未知数量的谓词?众所周知,它看起来有点丑陋。 问题答案: 我假设您的类型不同于,这意味着需要对其进行调整。一种可行的方法如下: 这会为每个谓词评估重新创建过滤器流带
问题内容: 基于python,用pandas排序降序数据框: 鉴于: df如下所示: 我想要类似的东西: 这应该相对于列“ x”和“ y”的平方值的总和来排序完整的数据框,然后给我: 升序或降序无关紧要。有没有一个简单而好的方法?我找不到解决方案。 问题答案: df.iloc[(df.x 2 + df.y 2).sort_values().index] 在如何根据字符串索引上的自定义顺序对熊猫数据
我试图为数据集创建多水平条形图。这些数据涉及跑步比赛的比赛时间。 Dataframe有以下列:名称、年龄组、完成时间、完成地点、家乡。下面是示例数据。 我想创建一个类似下图的条形图。每个年龄组将有一个条形图,最快的跑步者在图表的底部,跑步者的名字与城市和次数跑了比赛低于他们的名字。 我需要一个for循环还是一个简单的groupby工作?每个年龄组的数量和大小可以根据种族动态变化,因此它不是一个常数
问题内容: 我的数据有年龄,还有每月付款。 我正在尝试汇总付款总额,但不汇总年龄(平均有效)。 是否可以对不同的列使用不同的功能? 问题答案: 您可以将列名作为键,将想要的函数作为值传递给字典。