【问题标题】:Split and sort Pandas DataFrame in Python在 Python 中拆分和排序 Pandas DataFrame
【发布时间】:2021-02-17 14:02:10
【问题描述】:

我有一个熊猫数据框

         values
0      x15_2_30
1     x15_3_137
2      x15_6_26
3     x15_9_139
4    x15_10_143
..          ...
266  x208_6_153
267  x210_2_147
268  x211_1_155
269   x212_3_28
270   x212_5_25

我想根据中间数字的升序对这个数据框进行排序,而不是最后的数字。

首选输出是这样的

x15_1_4
x12_1_8
x25_1_12
....

【问题讨论】:

    标签: python-3.x pandas sorting split


    【解决方案1】:

    使用.str.extract() 用正则表达式一次性提取中间数字和最后一个数字:

    import pandas as pd
    from io import StringIO
    
    text = """
    values
    x15_6_30
    x15_6_26
    x15_3_137
    x15_9_139
    x15_10_143
    """
    
    df = pd.read_csv(StringIO(text), sep='\s+', header=0)
    
    df[['middle_number', 'last_number']] = df['values'].str.extract(
        pat='_([0-9]+)_([0-9]+)', 
        expand=True,
    ).astype(int)
    
    df.sort_values(by=['middle_number', 'last_number', 'values'])
    
    +----+------------+-----------------+---------------+
    |    | values     |   middle_number |   last_number |
    |----+------------+-----------------+---------------|
    |  2 | x15_3_137  |               3 |           137 |
    |  1 | x15_6_26   |               6 |            26 |
    |  0 | x15_6_30   |               6 |            30 |
    |  3 | x15_9_139  |               9 |           139 |
    |  4 | x15_10_143 |              10 |           143 |
    +----+------------+-----------------+---------------+
    

    更简单的解决方案是使用.str.split() 并在下划线处拆分。
    使用参数 .str.split(expand=True) 确保您从 3 个单独的列中获取所有 3 个值:

    df[['first_value', 'middle_value', 'last_value']] = df['values'].str.split(
        pat='_', 
        expand=True,
    )
    
    df[['middle_value', 'last_value']] = df[['middle_value', 'last_value']].astype(int)
    
    df = df.sort_values(by=['middle_value', 'last_value', 'first_value'])
    
    +----+------------+---------------+----------------+--------------+
    |    | values     | first_value   |   middle_value |   last_value |
    |----+------------+---------------+----------------+--------------|
    |  2 | x15_3_137  | x15           |              3 |          137 |
    |  1 | x15_6_26   | x15           |              6 |           26 |
    |  0 | x15_6_30   | x15           |              6 |           30 |
    |  3 | x15_9_139  | x15           |              9 |          139 |
    |  4 | x15_10_143 | x15           |             10 |          143 |
    +----+------------+---------------+----------------+--------------+
    

    【讨论】:

    • 顺便说一句,我像你一样分裂了答案,但后来有人解释我这是错误的(但这是大约 3 年前,所以我不记得原因),所以我停止了。跨度>
    • @jezrael:社区压力,我猜这是不成文的规定。尽管我更喜欢针对不同的答案发布单独的帖子,并让选民决定哪个答案是最好的。如果我读到这篇文章,我会说最好发布不同的答案:meta.stackexchange.com/questions/25209/…
    • @jezrael:从那篇帖子中引用了一个有趣的引述:如果您将两个截然不同的答案放在一个中,那么一个可能是一个很好的答案,一个可能是一种糟糕的做事方式,但是赞成对好(或坏)答案的(或否决)会将另一个与它一起拖到顶部(或底部)。
    • yop,同意,应该是不成文的规定
    【解决方案2】:

    创建一个列temp,在其中使用str.split().str[index] 分配最后一个_ 之后的值。使用它进行排序,然后删除列

    #If Using Last Number
    df.assign(temp=df['values'].str.split('_').str[2]).sort_values(by='temp', ascending=False).drop('temp',1)
    
    
    
        values
    0      x15_2_30
    269   x212_3_28
    2      x15_6_26
    270   x212_5_25
    268  x211_1_155
    266  x208_6_153
    267  x210_2_147
    4    x15_10_143
    3     x15_9_139
    1     x15_3_137
    

    【讨论】:

      猜你喜欢
      • 2015-04-11
      • 1970-01-01
      • 2018-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-29
      • 2021-01-25
      • 1970-01-01
      相关资源
      最近更新 更多