Pandas:df.groupby(x, y).apply() 跨多个列参数错误
Posted
技术标签:
【中文标题】Pandas:df.groupby(x, y).apply() 跨多个列参数错误【英文标题】:Pandas: df.groupby(x, y).apply() across multiple columns parameter error 【发布时间】:2013-08-01 04:26:21 【问题描述】:基本问题:
我有几个“过去”和“现在”变量,我想对它们执行简单的“row-wise”百分比变化。例如:((exports_now - exports_past)/exports_past))
。
这两个问题实现了这一点,但是当我尝试类似的方法时,我收到一个错误,即我的函数 deltas 获得了一个未知参数 axis
。
数据示例:
exports_ past exports_ now imports_ past imports_ now ect.(6 other pairs)
.23 .45 .43 .22 1.23
.13 .21 .47 .32 .23
0 0 .41 .42 .93
.23 .66 .43 .22 .21
0 .12 .47 .21 1.23
按照第一个问题的答案,
我的解决方案是使用这样的函数:
def deltas(row):
'''
simple pct change
'''
if int(row[0]) == 0 and int(row[1]) == 0:
return 0
elif int(row[0]) == 0:
return np.nan
else:
return ((row[1] - row[0])/row[0])
并像这样应用函数:
df['exports_delta'] = df.groupby(['exports_past', 'exports_now']).apply(deltas, axis=1)
这会产生这个错误:TypeError: deltas() got an unexpected keyword argument 'axis'
关于如何解决轴参数错误的任何想法?或者更优雅的计算 pct 变化的方法?我的问题的关键是我需要能够在几个不同的列对中应用这个函数,所以像第二个问题中的答案那样硬编码列名是不可取的。谢谢!
【问题讨论】:
【参考方案1】:考虑使用pct_change
Series/DataFrame 方法来执行此操作。
df.pct_change()
混淆源于两个不同(但名称相同)apply
函数,一个在 Series/DataFrame 上,一个在 groupby 上。
In [11]: df
Out[11]:
0 1 2
0 1 1 1
1 2 2 2
DataFrame apply 方法接受一个轴参数:
In [12]: df.apply(lambda x: x[0] + x[1], axis=0)
Out[12]:
0 3
1 3
2 3
dtype: int64
In [13]: df.apply(lambda x: x[0] + x[1], axis=1)
Out[13]:
0 2
1 4
dtype: int64
groupby apply 没有,kwarg 被传递给函数:
In [14]: g.apply(lambda x: x[0] + x[1])
Out[14]:
0 2
1 4
dtype: int64
In [15]: g.apply(lambda x: x[0] + x[1], axis=1)
TypeError: <lambda>() got an unexpected keyword argument 'axis'
注意:groupby 确实有一个轴参数,所以如果你真的想的话,你可以在那里使用它:
In [16]: g1 = df.groupby(0, axis=1)
In [17]: g1.apply(lambda x: x.iloc[0, 0] + x.iloc[1, 0])
Out[17]:
0
1 3
2 3
dtype: int64
【讨论】:
感谢您的回答安迪。如果我坚持使用 groupby 应用并删除轴参数,我会收到一个关键错误KeyError: u'no item named 0'
以访问 row[0]
等元素。有没有办法使用 groupby apply 并且仍然使用一种表示法,可以轻松地应用于几个不同命名的列对?
我想到了df.pct_change()
函数,但我相信它只适用于单个列。 IE。 df.pct_change(self, periods=1, fill_method='pad', limit=None, freq=None, **kwd)
。我没有检查源代码,但我相信它通过类似于.shift()
方法的方式来完成它。如果这是真的,我不确定它是否可以应用于多个列。
@agconti 已更新,您可以使用axis=1 的groupby,您可以将pct_change 应用于整个数据框。或者,也许您想使用应用 (lambda x: x.pct_change()
) 为每个组执行此操作。
我认为我的帖子中没有 100% 清楚。 (我更新了它)。我希望不通过在exports_past 和现在的exports 中移动期间而是通过使用这些值来进行pct_change() 计算。 IE。 ((exports_now - exports_past)/exports_past)
.
将axis=1 传递给groupby 会导致ValueError: Wrong number of items passed 1, indices imply 0
像这样使用:df['xx_delta'] = df.groupby(['xx_past', 'xx_now'], axis=1).apply(deltas)
以上是关于Pandas:df.groupby(x, y).apply() 跨多个列参数错误的主要内容,如果未能解决你的问题,请参考以下文章
Pandas - Groupby 多索引级别,获取可能的组合,然后转换数据
Python Pandas groupby 应用 lambda 参数
python – Pandas使用groupby中的count来创建新列