使用sort_values()独立地对pandas DataFrame的所有列进行排序

5
我有一个数据框,想要独立地按升序或降序排序所有列。
import pandas as pd

data = {'a': [5, 2, 3, 6],
        'b': [7, 9, 1, 4],
        'c': [1, 5, 4, 2]}
df = pd.DataFrame.from_dict(data)
   a  b  c
0  5  7  1
1  2  9  5
2  3  1  4
3  6  4  2

当我使用 sort_values() 时,它并没有按照我的预期进行排序,只对一列进行了排序:

foo = df.sort_values(by=['a', 'b', 'c'], ascending=[False, False, False])
   a  b  c
3  6  4  2
0  5  7  1
2  3  1  4
1  2  9  5

如果我使用这个答案提供的lambda函数解决方案,就可以得到想要的结果:

bar = df.apply(lambda x: x.sort_values().values)
print(bar)

   a  b  c
0  2  1  1
1  3  4  2
2  5  7  4
3  6  9  5

但是,我认为这看起来有点笨重。

实际上,在上面的sort_values()示例中发生了什么,如何以pandas的方式对数据框中的所有列进行排序而不使用lambda函数?

2个回答

11
你可以在 DataFrame 构造函数中使用 numpy.sort
df1 = pd.DataFrame(np.sort(df.values, axis=0), index=df.index, columns=df.columns)
print (df1)
   a  b  c
0  2  1  1
1  3  4  2
2  5  7  4
3  6  9  5

编辑:

以降序回答:

arr = df.values
arr.sort(axis=0)
arr = arr[::-1]
print (arr)
[[6 9 5]
 [5 7 4]
 [3 4 2]
 [2 1 1]]

df1 = pd.DataFrame(arr, index=df.index, columns=df.columns)
print (df1)
   a  b  c
0  6  9  5
1  5  7  4
2  3  4  2
3  2  1  1

谢谢你的回答。但我仍然更喜欢 df.apply(lambda x: x.sort_values().values),因为它更短,不需要导入numpy。 - Cord Kaldemeyer
难道没有一些标准的pandas构造可以做到这一点吗? ;) - Cord Kaldemeyer
11
当使用pandas时,不应该因为要避免导入numpy而偏好避免使用numpy。这是因为当你导入pandas时,已经导入了numpy。事实上,你可以使用pandas命名空间来完成和jezrael一样的操作。即pd.DataFrame(pd.np.sort(df.values, axis=0), index=df.index, columns=df.columns) - piRSquared
@piRSquared 感谢您的评论。 - jezrael
感谢你们两位的帮助和解释! - Cord Kaldemeyer
显示剩余2条评论

5
sort_values函数将按照你传递给它的列顺序对整个数据框进行排序。在你的第一个例子中,你使用['a', 'b', 'c']对整个数据框进行排序。这将按照'a''b'和最后'c'的顺序进行排序。
请注意,在按a排序后,行保持不变。这是期望的结果。
使用lambda表达式可以将每个列传递给该函数,这意味着sort_values函数将只应用于单个列,因此这种方法按预期对列进行排序。在这种情况下,行会发生改变。
如果你不想使用lambdanumpy,可以使用以下方式实现:
pd.DataFrame({x: df[x].sort_values().values for x in df.columns.values})

输出:

   a  b  c
0  2  1  1
1  3  4  2
2  5  7  4
3  6  9  5

@CordKaldemeyer 用新的排序方式编辑了 df,不使用 lambdanumpy - Carles Mitjans
感谢你们两位的帮助和解释! - Cord Kaldemeyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接