【问题标题】:Sorting a Column of Lists of Strings by the containing Number按包含的数字对一列字符串列表进行排序
【发布时间】:2021-08-02 01:23:21
【问题描述】:

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

我的尝试
我试图通过用, 拆分字符串来解决它,分解它,然后用- 再次拆分它,并修剪结果子列表的每个字符串。所以现在我得到了每个双页的列表,起始页和结束页有 2 个字符串 -> 例如['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']

【问题讨论】:

    标签: python pandas string sorting


    【解决方案1】:

    您需要将页码转换为 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
    

    【讨论】:

    • 非常感谢,这是主要问题。关于如何尽可能简短地将 Pages 列转换回一个长字符串的任何建议?我倾向于过度使用列表理解。然而,我并不完全在那里,这就是我到目前为止得到的 df['new_page'] = [l[1:-1].replace(","," -") for l in df['Pages']]
    • @SysRIP 更新了答案。
    • 非常感谢。没有害处,但会接受 Shubham 的回答。我赞成你的
    【解决方案2】:

    我们可以对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
    

    【讨论】:

      猜你喜欢
      • 2017-08-11
      • 2021-08-12
      • 1970-01-01
      • 2016-03-13
      • 1970-01-01
      • 2021-02-22
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      相关资源
      最近更新 更多