首页 > 解决方案 > 如何根据熊猫中的另一列数组对一列数组进行排序?

问题描述

我有一个这样的数据框:

df1= pd.DataFrame({
    'col1': [np.asarray([1,4,3,2]), np.asarray([9,10,7,5]), np.asarray([100,120,10,22])],
    'col2': [np.asarray([0,1,4,5]), np.asarray([100,101,102,103]), np.asarray([10,11,12,13])]
})

df1
                 col1                  col2
0        [1, 4, 3, 2]          [0, 1, 4, 5]
1       [9, 10, 7, 5]  [100, 101, 102, 103]
2  [100, 120, 10, 22]      [10, 11, 12, 13]

我想根据第 1 列中的数组值对第 2 列中的数组值进行排序。

这是我的解决方案:

sort_idx = df1['col1'].apply(np.argsort).values
for rowidxval, (index, row) in enumerate(df1.iterrows()):
    df1['col1'][index] = df1['col1'][index][sort_idx[rowidxval]]
    df1['col2'][index] = df1['col2'][index][sort_idx[rowidxval]]

是否有一种优雅的、pythonic 的方式来代替暴力对数据帧进行逐行排序?如果我想根据第 1 列中的值对多个列进行重新排序怎么办?

标签: pythonpandasdataframe

解决方案


从不推荐列中的列表(混合 dtype 和可变 dtype 会在代码中引入瓶颈和性能降低),但您可以使用列表推导尽可能快地做到这一点:

df['col2'] = [np.array(y)[np.argsort(x)] for x, y in zip(df.col1, df.col2)]
df

                 col1                  col2
0        [1, 4, 3, 2]          [0, 5, 4, 1]
1       [9, 10, 7, 5]  [103, 102, 100, 101]
2  [100, 120, 10, 22]      [12, 13, 10, 11]

如果它们都是数组,则解决方案会简化:

df['col2'] = [y[x.argsort()] for x, y in zip(df.col1, df.col2)]
df

                 col1                  col2
0        [1, 4, 3, 2]          [0, 5, 4, 1]
1       [9, 10, 7, 5]  [103, 102, 100, 101]
2  [100, 120, 10, 22]      [12, 13, 10, 11]

有关性能相关问题的更多信息,请参阅For loops with pandas 中的“混合 dtypes”部分 - 我应该何时关心?.


推荐阅读