为何DataFrame.nlargest多列筛选结果未按指定顺序排序?
关于Pandas 0.22.0中
nlargest()多列筛选结果排序的疑问解答 嘿,这个问题我当初用旧版Pandas的时候也踩过坑!咱们一步步来拆解:
首先先还原你的示例代码和输出:
import pandas as pd import numpy as np # 构建示例DataFrame df = pd.DataFrame({ 'a': [-2, -1, 1, 10, 8, 11, -1], 'b': list('abdceff'), 'c': [1.0, 2.0, 4.0, 3.2, np.nan, 3.0, 4.0] }) # 多列调用nlargest df.nlargest(5, ['a', 'c'])
得到的输出是:
Out[332]:
a b c
6 -1 f 4.0
5 11 f 3.0
3 10 c 3.2
4 8 e NaN
2 1 d 4.0
为什么看起来没按a→c的顺序排序?
核心原因是Pandas 0.22.0版本的nlargest()在多列筛选时,只负责选出符合条件的前N行,不会对最终结果做严格的排序!
它的筛选逻辑是:
- 优先按第一列
a筛选出数值最大的候选行 - 当
a列值相同时,再用c列来筛选出更大的行
但这个版本的底层实现(用堆结构来高效筛选)并没有对最终选出的行按照a→c的降序做二次排序,结果的顺序是由筛选过程中数据的扫描顺序决定的,所以才会出现a=-1的行排在最前面的情况。
而单列调用时,筛选逻辑简单,堆结构取出的结果自然是按该列降序排列的,所以你看到的结果是有序的。
怎么得到预期的有序结果?
在0.22.0版本里,你只需要在nlargest()之后额外调用sort_values(),强制按指定列排序:
# 先筛选再排序,得到严格按a降序、c降序的前5行 df.nlargest(5, ['a', 'c']).sort_values(['a', 'c'], ascending=False)
这样就能得到你预期的结果:
a b c
5 11 f 3.0
3 10 c 3.2
4 8 e NaN
2 1 d 4.0
6 -1 f 4.0
另外补充一句:这个问题在Pandas 0.23.0及以上的版本已经被修复了,新版本的nlargest()多列筛选会自动按照指定列的顺序降序排列,不需要额外手动排序。
内容的提问来源于stack exchange,提问作者DMO
相关产品推荐
相关产品推荐

