【问题标题】:pandas dataframe sort_values on multiple columns did not work all the time多列上的熊猫数据框 sort_values 并非一直有效
【发布时间】:2017-10-11 19:06:55
【问题描述】:

我有这 2 个 pandas 数据框,我尝试以相同的方式对它们进行排序,但得到不同的结果

将熊猫导入为 pd

df = pd.DataFrame([{'a':'4','b':'23'},{'a':'3', 'b':'10'},{'a':'2','b':'88'},{'a':'2', 'b':'29'},{'a':'2','b':'12'},{'a':'1','b':'284'}, {'a':'1','b':'24'}, {'a':'3','b':'1'}])

print(df.sort_values(['a', 'b']))

df1 = pd.DataFrame([{'c1':'3','c2':'10'},{'c1':'2', 'c2':'30'},{'c1':'1','c2':'20'},{'c1':'2','c2':'15'},{'c1':'2','c2':'100'},{'c1':'1','c2':'11'}])

print(df1.sort_values(['c1', 'c2']))

第一个返回,这是预期的

   a    b
6  1   24
5  1  284
4  2   12
3  2   29
2  2   88
7  3    1
1  3   10
0  4   23

第二个返回

   c1   c2
5  1   11
2  1   20
4  2  100
3  2   15
1  2   30
0  3   10

我认为它会返回

  c1   c2
5  1   11
2  1   20
4  2   15
3  2   30
1  2  100
0  3   10

有人能告诉我为什么他们的行为不同吗?谢谢。

【问题讨论】:

    标签: string sorting pandas


    【解决方案1】:

    您的数据是字符串而不是数字存在问题,因此按字母顺序排序。

    解决方案是将列转换为int

    df1['c2'] = df1['c2'].astype(int)
    print(df1.sort_values(['c1', 'c2']))
      c1   c2
    5  1   11
    2  1   20
    3  2   15
    1  2   30
    4  2  100
    0  3   10
    

    【讨论】:

    • 嗨,jezreal,感谢您的回复。就我而言,我需要按多列排序,其中一些是字符串。有没有一种方法可以使数据框的 sort_values 的行为方式与 sql 中的 ORDER BY 相同?
    • 嗯,没那么容易。但是您是否需要像数字一样对字符串数字(在您的示例中)进行排序?不可能转成数字吗?
    • 我在这里给出的例子仅用于演示。我知道如果我为这些数字提供 int , sort 将起作用。在我的真实案例中,我有来自 excel 表的数据框和来自 sql 查询的数据框。我已将 sql 查询数据帧转换为字符串(使用 applymap(str)),因为某些数字具有前导或尾随零。我想我需要将数字列转换回 int 并对两个数据帧进行排序。谢谢。
    • 嗯,没有真实数据并不容易,但我认为最简单的方法是先将所有 int 转换为 df[['int_col1','int_col2','int_col3']] = df[['int_col1','int_col2','int_col3']].astype(int),然后排序并最后转换为数字。 df[['int_col1','int_col2','int_col3']] = df[['int_col1','int_col2','int_col3']].astype(str)。但也许还有另一个问题,您是否通过转换为 str 来删除尾随 0 ?是正确的方式吗?不可能先排序再转成str
    • 是的,我使用 df['int_col1'].replace(to_replace="(\d+)\.0", value=r"\1", regex=True, inplace=True) 感谢 jezrael。
    猜你喜欢
    • 2021-09-02
    • 2019-12-02
    • 1970-01-01
    • 2021-03-06
    • 2016-07-24
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多