我正在研究在熊猫DataFrame上使用嵌套groupby.apply的问题。在第一个应用中,我将添加一个列,用于第二个内部groupby.apply。合并的结果对我来说似乎是错误的。谁能向我解释为什么出现以下现象以及如何可靠地解决它?
这是一个最小的示例:
import numpy as np
import pandas as pd
T = np.array( [
[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, columns= ['a','b','c' ])
print(df)
def foo2(x):
return x
def foo(x):
print("*" * 80 )
# Add column d and groupby/apply on column 'd'
x['d'] = [1, 1, 2, 2]
x = x.groupby('d').apply(foo2)
print(x)
print("*" * 80)
return x
# Apply first groupby/apply on column 'a'
df = df.groupby('a').apply( foo)
print("*"*80)
print("*"*80)
print(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
答案 0 :(得分:1)
[Mac,Python:3.6.8]
我的想法是,嵌套DataFrame.apply
的预期行为将有点难以调试。我的建议是通过仿效apply
(即先映射再缩小)来实现目标:
map
方法,然后pandas.concat
合并结果import numpy as np
import pandas as pd
def my_apply(df, f):
return pd.concat(map(f, df))
def foo(x):
group, grouped = x
grouped['d'] = [1, 1, 2, 2]
return grouped.groupby('d').apply(lambda x: x)
T = np.array([[1,1,1]]*2 + [[1,2,2]]*2 +
[[2,1,3]]*2 + [[2,2,4]]*2)
df = pd.DataFrame(T, columns= ['a','b','c' ])
df = my_apply(df.groupby('a'), foo)
print(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
注意:
foo2
替换为lambda
,随时可以调换。A value is trying to be set on a copy of a slice from a DataFrame [...]
。这是因为我们故意设置副本的值。这是预期的行为,而不是错误。不幸的是,pandas
将此操作解释为错误,因为通常可能是错误的。