代码之家  ›  专栏  ›  技术社区  ›  U13-Forward

按另一个数据框中的列对熊猫数据框进行排序-熊猫

  •  0
  • U13-Forward  · 技术社区  · 5 年前

    假设我有一个带有两列的熊猫数据框,比如:

    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
    

    有没有办法做到这一点?

    请检查下面的自我回答。

    2 回复  |  直到 5 年前
        1
  •  3
  •   Allen Qin    5 年前

    那么:

    (
        df.assign(s=s)
        .sort_values(by='s')
        .drop('s', axis=1)
    )
    
        2
  •  2
  •   U13-Forward    5 年前

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

    解决:

    解决方案1:

    set_index 转换 a 列,然后使用 reindex 要更改顺序,请使用 rename_axis 将索引名称更改回 A. ,然后使用 reset_index 转换 A. 从索引返回到列的列:

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

    解决方案2:

    使用 集合索引 转换 A. 列,然后使用 loc 要更改顺序,请使用 重置索引 转换 A. 从索引返回到列的列:

    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对象,请使用 sorted 用一个 key 参数按 s 系列:

    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
    

    @艾伦也有一个很好的答案。