按包含的编号对字符串列表列进行排序

2024-06-28 18:58:53 发布

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

我想创建一个作者索引。
在我的数据框中,我有一列是作者的,另一列是每个页面的长字符串 作者的姓名出现在屏幕上。因为我接收这些数字的文档总是双页的,所以它总是类似于3 - 417 - 18

我所尝试的
我试图通过按,拆分字符串,分解它,再按-再次拆分它,并修剪结果子列表的每个字符串来解决它。因此,现在我得到了每个双页的列表,起始页和结束页都有两个字符串->;e、 g.['8','9']

目标目标
从每个作者的列表中,我想按起始页(每个列表中的第一个条目)对它们进行排序,但我想不出来。在下面的最小重现性示例中,指数2应为 ['8','9']['158','159',['178','179']

甚至更好地转换回一个长字符串 '8 - 9, 158 - 159, 178 - 179'

MRE

import pandas as pd
data = {'Author': ["AAA, Anton","CCC, Berthelm","DDD, Greta"],
        'Page': ["16 - 17", "238 - 239", "178 - 179, 158 - 159, 8 - 9"]}

df = pd.DataFrame(data=data)

df["Pages"] = df["Page"].str.split(',').explode().str.split(' - ').apply(lambda x: [s.lstrip() for s in x])\
                        .sort_values().groupby(level=0).agg(lambda x: ', '.join(map(str, x)))

打印输出

          Author  ...                                       Pages
0     AAA, Anton  ...                                ['16', '17']
1  CCC, Berthelm  ...                              ['238', '239']
2     DDD, Greta  ...  ['158', '159'], ['178', '179'], ['8', '9']

Tags: 字符串目标df列表data作者authorpd
2条回答

您需要将页码强制转换为int而不是字符串

df["Pages"] = df["Page"].str.split(',').explode().str.split(' - ').apply(lambda x: [int(s.lstrip()) for s in x])\
                        .sort_values().groupby(level=0).agg(lambda x: ', '.join(map(str, x)))

输出

          Author                         Page                           Pages
0     AAA, Anton                      16 - 17                        [16, 17]
1  CCC, Berthelm                    238 - 239                      [238, 239]
2     DDD, Greta  178 - 179, 158 - 159, 8 - 9  [8, 9], [158, 159], [178, 179]

如果您希望以字符串格式返回输出,只需更改agg()

df["Page"] = df["Page"].str.split(',').explode().str.split(' - ').apply(lambda x: [int(s.lstrip()) for s in x])\
                        .sort_values().groupby(level=0).agg(lambda x: ', '.join(f'{start} - {end}' for start, end in x))

输出

          Author                         Page
0     AAA, Anton                      16 - 17
1  CCC, Berthelm                    238 - 239
2     DDD, Greta  8 - 9, 158 - 159, 178 - 179

我们可以使用列表理解来splitsort,然后join返回列Page中的字符串

df['Page'] = [', '.join(sorted(s.split(', '), key=lambda s: int(s.split(' - ')[0]))) for s in df['Page']]

          Author                         Page
0     AAA, Anton                      16 - 17
1  CCC, Berthelm                    238 - 239
2     DDD, Greta  8 - 9, 158 - 159, 178 - 179

相关问题 更多 >