【问题标题】:Sort a pandas DataFrame by a column in another dataframe - pandas按另一个数据帧中的列对熊猫数据帧进行排序 - 熊猫
【发布时间】:2020-05-12 11:28:33
【问题描述】:

假设我有一个包含两列的 Pandas DataFrame,例如:

df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [100, 200, 300, 400]})
print(df)

   a    b
0  1  100
1  2  200
2  3  300
3  4  400

假设我也有一个熊猫系列,比如:

s = pd.Series([1, 3, 2, 4])
print(s)

0    1
1    3
2    2
3    4
dtype: int64

如何将a 列排序为与s 系列相同的顺序,并将相应的行值排序在一起?

我想要的输出是:

   a    b
0  1  100
1  3  300
2  2  200
3  4  400

有什么办法可以做到吗?

请检查下面的自我回答。

【问题讨论】:

  • 是系列s completely separate from dataframe df? Where does it come from? It makes things easier if you concat series s` 到df。然后你可以简单地做df.sort_values('s')

标签: python pandas dataframe sorting series


【解决方案1】:

怎么样:

(
    df.assign(s=s)
    .sort_values(by='s')
    .drop('s', axis=1)
)

【讨论】:

    【解决方案2】:

    我经常遇到这些问题,所以我只想在 Pandas 中分享我的解决方案。

    解决方案:

    解决方案 1:

    使用set_indexa列转换为索引,然后使用reindex更改顺序,再使用rename_axis将索引名称改回a,然后使用reset_index为将a 列从索引转换回列:

    print(df.set_index('a').reindex(s).rename_axis('a').reset_index('a'))
    

    解决方案 2:

    使用set_indexa 列转换为索引,然后使用loc 更改顺序,然后使用reset_indexa 列从索引转换回列:

    print(df.set_index('a').loc[s].reset_index())
    

    解决方案 3:

    使用iloc 以不同的顺序索引行,然后使用map 获得适合df 的顺序,使其与s 系列一起排序:

    print(df.iloc[list(map(df['a'].tolist().index, s))])
    

    解决方案 4:

    使用pd.DataFrame 创建一个新的DataFrame 对象,然后使用sortedkey 参数按s 系列对DataFrame 进行排序:

    print(pd.DataFrame(sorted(df.values.tolist(), key=lambda x: s.tolist().index(x[0])), columns=df.columns))
    

    时间安排:

    用下面的代码计时:

    import pandas as pd
    from timeit import timeit
    df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [100, 200, 300, 400]})
    s = pd.Series([1, 3, 2, 4])
    def u10_1():
        return df.set_index('a').reindex(s).rename_axis('a').reset_index('a')
    def u10_2():
        return df.set_index('a').loc[s].reset_index()
    def u10_3():
        return df.iloc[list(map(df['a'].tolist().index, s))]
    def u10_4():
        return pd.DataFrame(sorted(df.values.tolist(), key=lambda x: s.tolist().index(x[0])), columns=df.columns)
    print('u10_1:', timeit(u10_1, number=1000))
    print('u10_2:', timeit(u10_2, number=1000))
    print('u10_3:', timeit(u10_3, number=1000))
    print('u10_4:', timeit(u10_4, number=1000))
    

    输出:

    u10_1: 3.012849470495621
    u10_2: 3.072132612502147
    u10_3: 0.7498072134665241
    u10_4: 0.8109911930595484
    

    @Allen 也有一个很好的答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-18
      • 2021-05-08
      • 2019-04-12
      • 2013-12-20
      相关资源
      最近更新 更多