Pandas 在 GroupBy 对象上应用 sort_values 不会返回分组的 DataFrame
Posted
技术标签:
【中文标题】Pandas 在 GroupBy 对象上应用 sort_values 不会返回分组的 DataFrame【英文标题】:Pandas apply sort_values on GroupBy object does not return a grouped DataFrame 【发布时间】:2021-01-13 12:22:09 【问题描述】:我不明白为什么下面的代码不起作用。我有以下数据框:
ind = pd.MultiIndex.from_tuples([(2, 9), (2, 0), (3, 15), (3, 8), (2, 28), (2, 15), (2, 10), (3, 9)], names=['A','B'])
values = [0.2719, 0.2938, 0.3281, 0.3310, 0.3323, 0.3640, 0.3647, 0.5218]
df = pd.DataFrame(data = values, index=ind, columns = ['values'])
应用 groupby sort_values 不会做任何事情:
df.groupby('A').apply(lambda x: x.sort_values(by='values'))
请注意,这些值已经全局排序。
现在,当我只是交换两行,从而破坏全局优先排序时,它突然起作用了:
df1 = df.iloc[np.r_[1,0,2:len(df)]]
df1.groupby('A').apply(lambda x: x.sort_values(by='values'))
这也是我期望从其他代码中得到的结果。
【问题讨论】:
我认为像df.groupby('A').apply(lambda x:x)
这样的简单操作也不会创建分组数据框。所以也许我只是不明白 groupby 什么时候会重新排序结果数据帧,什么时候不会。
【参考方案1】:
文档中关于split-apply-combine
的combine
部分并没有说太多:
GroupBy 将检查应用步骤的结果并尝试返回合理组合的结果。
由于您在第一个示例中没有更改行数或其顺序,apply
的功能更像transform
,它返回一个“类似索引的对象”。
我想如果你想要的是嵌套排序,你可以直接将一个列表传递给sort_values
,就像这样:
df.sort_values(["A", "values"])
values
A B
2 9 0.2719
0 0.2938
28 0.3323
15 0.3640
10 0.3647
3 15 0.3281
8 0.3310
9 0.5218
【讨论】:
为了便于预测,我采用了您引用的那种代码。我不明白的是 groupby apply 怎么会如此不稳定。我的意思是,现在我知道在 groupby 应用操作中进行排序是个坏主意,因为它会产生不可预测的结果。但是我不能用 groupby apply 做什么,这会让我感到沮丧。我也许应该向 pandas github 组报告这种行为。在我看来,行为应该是一致的。既适用于您给出排序与未排序的情况,也适用于执行索引与列操作的情况。 我的意思是考虑一下:当数据帧已经全局排序时,不会插入额外的 multiIndex 列,但你不会得到额外的列。代码如何处理这个问题?本质上,代码要么必须事先检查数据帧是否已经排序,要么必须明确检查重复的索引级别。以上是关于Pandas 在 GroupBy 对象上应用 sort_values 不会返回分组的 DataFrame的主要内容,如果未能解决你的问题,请参考以下文章
在 groupby 熊猫对象上应用 rolling() 时,多索引重复
如何在 pandas groupby 对象上调用不同的聚合操作