Python 嵌套的groupby给出了意外的结果
我正在处理一个问题,其中我在数据帧上使用嵌套的groupby.apply。在第一次应用期间,我添加了一列,用于第二个内部groupby.apply。在我看来,综合结果是错误的。有谁能向我解释一下为什么会出现以下现象,以及如何可靠地修复它 下面是一个简单的例子:Python 嵌套的groupby给出了意外的结果,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我正在处理一个问题,其中我在数据帧上使用嵌套的groupby.apply。在第一次应用期间,我添加了一列,用于第二个内部groupby.apply。在我看来,综合结果是错误的。有谁能向我解释一下为什么会出现以下现象,以及如何可靠地修复它 下面是一个简单的例子: 将numpy导入为np 作为pd进口熊猫 T=np.数组([ [1,1,1], [1,1,1], [1,2,2], [1,2,2], [2,1,3], [2,1,3], [2,2,4], [2,2,4], ]) df=pd.DataFra
将numpy导入为np
作为pd进口熊猫
T=np.数组([
[1,1,1],
[1,1,1],
[1,2,2],
[1,2,2],
[2,1,3],
[2,1,3],
[2,2,4],
[2,2,4],
])
df=pd.DataFrame(T,列=['a','b','c'])
打印(df)
def foo2(x):
返回x
def foo(x):
打印(“*”*80)
#添加列d和列“d”上的groupby/apply
x['d']=[1,1,2,2]
x=x.groupby('d')。应用(foo2)
打印(x)
打印(“*”*80)
返回x
#应用第一个groupby/在列“a”上应用
df=df.groupby('a')。apply(foo)
打印(“*”*80)
打印(“*”*80)
打印(df)
当我在我的Windows笔记本电脑上运行上述代码时,我得到了预期的结果
a b c d
A.
1 0 1 1 1 1
1 1 1 1 1
2 1 2 2 2
3 1 2 2 2
2 4 2 1 3 1
5 2 1 3 1
6 2 2 4 2
7 2 2 4 2
在Mac上运行相同的代码
a b c d
A.
1 0 1 1 1 1
1 1 1 1 1
2 1 2 2 2
3 1 2 2 2
2 4 1 1 3 1
5 1 1 3 1
6 1 2 4 2
7 1 2 4 2
这里的问题是,在列“a”中,最后4个条目是1,而在Windows计算机上,它们应该是2
编辑:
两个版本上的熊猫:0.24.2
Windows上的Python版本:3.7.3
Mac上的Python版本:3.7.4
我的想法是,嵌套的DataFrame.apply的预期行为在调试时会有点复杂。我的建议是,通过模仿您希望从应用
(即先映射,然后减少)中实现的目标来切入主题:
Map:使用python的本机Map
方法,后跟
减少:使用pandas.concat
组合结果
将numpy导入为np
作为pd进口熊猫
def my_应用(df,f):
返回pd.concat(地图(f,df))
def foo(x):
组,分组=x
分组['d']=[1,1,2,2]
返回grouped.groupby('d').apply(lambda x:x)
T=np.数组([[1,1,1]]*2+[[1,2,2]]*2+
[[2,1,3]]*2 + [[2,2,4]]*2)
df=pd.DataFrame(T,列=['a','b','c'])
df=my_apply(df.groupby('a'),foo)
打印(df)
结果:
a b c d
0 1 1 1 1
1 1 1 1 1
2 1 2 2 2
3 1 2 2 2
4 2 1 3 1
5 2 1 3 1
6 2 2 4 2
7 2 2 4 2
注:
我没有试图解决导致Mac/Windows之间性能差异的实现/架构差异]
我已经缩小了您的示例,将foo2
替换为lambda
,请随意调回
上述代码将抛出以下警告试图在数据帧[…]的切片副本上设置值。这是因为我们故意设置副本的值。这是预期的行为,而不是bug。不幸的是,pandas
将此操作解释为错误,因为它通常可能是错误的
请在这两个版本以及python版本上发布pandas版本谢谢,我进行了编辑。这可能与pandas失败的原因有关:SettingWithCopyWarning:试图在数据帧的切片副本上设置值。尝试使用.loc[row\u indexer,col\u indexer]=value,请参见文档中的注意事项:grouped['d']=[1,1,2,2]。我已添加了有关(预期)警告的说明。您可以禁用它,但真正的解决方法是使用grouped.copy()
创建grouped
对象的副本,但是对于性能不太好的大型数据帧,我认为最好还是使用警告。我很怀疑这是否与问题有关。我最好的猜测是,在Mac版的熊猫中,群体指数正在被某个地方吸收。在实践中,apply和group by方法可能并不打算以这种方式进行操作。