基于最近的一个问题,我想知道在应用于 groupby
的函数内使用 inplace=True
对组进行排序时到底出了什么问题>.
示例和问题
df = pd.DataFrame({'A': ['a', 'a', 'b'],
'B': [3, 2, 1]})
def func(x):
x.sort_values('B', inplace=True)
return x.B.max()
dfg = df.groupby('A')
dfg.apply(func)
这给出
A
a 3
b 3
虽然人们期望
A
a 3
b 1
在函数内打印 x
显示函数 func
在每次调用期间应用于组 'a'
(组 >'b'
被完全“替换”):
def func(x):
print(x)
x.sort_values('B', inplace=True)
return x.B.max()
# Output (including the usual pandas apply zero-call)
A B
0 a 3
1 a 2
A B
0 a 3
1 a 2
A B
1 a 2
0 a 3
问题的解决方案
可以通过在 func
内执行排序来解决此问题,例如 x = x.sort_values('B')
。在这种情况下,一切都按预期进行。
问题
现在我的概念问题:作为第一个想法,我期望
inplace
修改 DataFrame/DataFrameGroupBy 本身,而赋值x = x.sort_values('B')
创建副本- 这相当于在循环遍历列表时修改列表的 groupby
但是,对 Dataframe df 和 DataFrameGroupBy 实例 dfg 的检查显示,它们在应用
后没有发生变化,这表明问题不是修改原始实例。那么这里发生了什么?
最佳答案
当我这么做的时候
def func(x):
x = x.copy()
x.sort_values('B', inplace=True)
return x.B.max()
返回
A
a 3
b 1
所以它验证了你的第一个想法 即
- 就地修改 DataFrame/DataFrameGroupBy 本身,而
赋值x = x.sort_values('B')
创建一个副本
我也迭代了 dfg groupby 对象。
def func(x):
x = x.sort_values('B', inplace=True)
return x.B.max()
dfg = df.groupby('A')
for x in dfg:
print(func(x[1]))
返回
3
1
因此,根据我的理解,这个问题与 DataFrame.groupby().apply() 迭代其元素的方式有关。
它只是将相同的内存块分配给所有元素,一旦您使用 inplace=True
覆盖该 block ,它就会永久更新。
因此,您的 dfg 和 df 变量仍然具有原始值,但您仍然得到错误的输出。
关于python - 在 groupby 中使用 sort_values 和 inplace=True 时到底出了什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59227968/