如何根据由字母和数字组成的列对dataframe进行排序?

2024-09-29 23:26:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一个数据帧:

import pandas as pd

df = pd.DataFrame(
    {
        'pos': ['A1', 'B03', 'A2', 'B01', 'A3', 'B02'],
        'ignore': range(6)
    }
)
   pos  ignore
0   A1       0
1  A03       1
2   A2       2
3  B01       3
4   B3       4
5  B02       5

我想根据pos进行排序

  • 它应该先按数字排序,然后按字母和数字排序
  • 应忽略前导0

因此,理想的结果是

   pos  ignore
0   A1       0
1  B01       3
2   A2       2
3  B02       5
4  A03       1
5   B3       4

我现在是这样做的:

df[['let', 'num']] = df['pos'].str.extract(
    '([A-Za-z]+)([0-9]+)'
)
df['num'] = df['num'].astype(int)
df = (
    df.sort_values(['num', 'let'])
      .drop(['let', 'num'], axis=1)
      .reset_index(drop=True)
)

这是可行的,但我不喜欢的是,我需要两个临时列,以后必须再次删除。有没有更直接的方法


Tags: posa2df排序a1数字numdrop
2条回答

您可以将argsortzfill一起使用,并对数字进行第一次排序,如01, 02, 03等。这样您就不必分配/删除列:

val =  df['pos'].str.extract('(\D+)(\d+)')
df.loc[(val[1].str.zfill(2) + val[0]).argsort()]

   pos  ignore
0   A1       0
3  B01       3
2   A2       2
5  B02       5
4   A3       4
1  B03       1

这里有一个方法:

import re
def extract_parts(x):
    groups = re.match('([A-Za-z]+)([0-9]+)', x)
    return (int(groups[2]), groups[1])

df.reindex(df.pos.transform(extract_parts).sort_values().index).reset_index(drop=True)

输出

Out[1]: 
   pos  ignore
0   A1       0
1  B01       3
2   A2       2
3  B02       5
4  A03       1
5   B3       4

相关问题 更多 >

    热门问题