【问题标题】:Splitting string involving parenthesis, whilst retaining the parenthesis拆分涉及括号的字符串,同时保留括号
【发布时间】:2020-09-28 20:45:26
【问题描述】:

我在 df 中有一个名为 Roles 的列,其值如下所示:

ABCD (Actor), XYZ (Actor, Director), PQR (Producer, Writer)

我想拆分这个字符串,这样我得到一个包含每个人列表的值

所以输出应该是:

[[ABCD (Actor)], [XYZ (Actor, Director)], [PQR (Producer, Writer)]]

尝试使用以下内容,然而发生的情况是 ) 被剪切,我最终得到输出中没有 ) 的字符串

df['Role_Split'] = df['Roles'].str.split("\), ")

结果

['ABCD (Actor, XYZ (Actor, Director, PQR (Producer, Writer)']

此外,我的计划是创建新栏目,分别针对演员、导演、制片人等 如果列表元素包含字符串“演员”或“导演”或“制片人”等,则填充这些列

您能否建议是否有更简单的方法来做到这一点? 所以最终的输出

Some more columns   Roles       Role_Split   Actor    Other Roles
                    ABCD (Actor), XYZ (Actor, Director), PQR (Producer, Writer)        [[ABCD (Actor)], [XYZ (Actor, Director)], [PQR (Producer, Writer)]]    ABCD, XYZ      XYZ, PQR 
 

【问题讨论】:

    标签: python-3.x pandas


    【解决方案1】:

    看来你可以使用str.findall

    例如:

    df = pd.DataFrame({"Roles":['ABCD (Actor), XYZ (Actor, Director), PQR (Producer, Writer)']})
    df['Role_Split'] = df['Roles'].str.findall(r"(\w+ \(.*?\))")
    print(df['Role_Split'])  # print(df['Role_Split'][0]
    

    输出:

    ['ABCD (Actor)', 'XYZ (Actor, Director)', 'PQR (Producer, Writer)']
    

    根据评论编辑

    df = pd.DataFrame({"Roles":['ABCD Walters Sr (Actor), XYZ PQR AB (Lead Role, Producer, Director)']})
    df['Role_Split'] = df['Roles'].str.findall(r"([\w\s]+ \(.*?\))")
    print(df['Role_Split'][0])
    # ->['ABCD Walters Sr (Actor)', ' XYZ PQR AB (Lead Role, Producer, Director)']
    

    str.extractall 与命名的正则表达式组一起使用

    例如:

    df2 = df['Roles'].str.extractall(r"(?P<Actor>[\w\s]+) (?P<roles>\(.*?\))")
    print(df2)
    

    输出:

                       Actor                            roles
      match                                                  
    0 0      ABCD Walters Sr                          (Actor)
      1           XYZ PQR AB  (Lead Role, Producer, Director)
    

    【讨论】:

    • 名字不只是ABCD,而是ABCD Walters....所以上面的剧本,只保留了Walters(演员)... ABCD第一个字被抹掉了
    • 如果是这样,那么 re 模式应该是 r"([\w\s]+ \(.*?\))"
    • ABCD Walters Sr(演员)、XYZ PQR AB(主要角色、制片人、导演)
    • 我怎样才能进一步创建一个新列并且只包含包含字符串 Actor 的元素。所以 ABCD Walters Sr 应该是我的列值
    • 我以为我会遍历列表找到字符串,但是列表无法遍历?
    【解决方案2】:

    使用正则表达式和后向括号:

    (?<=\)),\s+
    

    它在逗号和逗号位于右括号之后的任何后续空格(至少需要一个前向空格)上分割。

    s = 'ABCD (Actor), XYZ (Actor, Director), PQR (Producer, Writer)'
    pd.Series([s]).str.split(r'(?<=\)),\s+', expand=True)
    

    产生如下输出:

    Out[5]: 
                  0                      1                       2
    0  ABCD (Actor)  XYZ (Actor, Director)  PQR (Producer, Writer)
    

    注意pd.Series.str.splittakes a regular expression直接输入。如果您想将其放入不同的列,请将expand=True 传递给您的s.str.split(pattern) 调用;否则,如果希望在每个系列单元格中都有一个列表,请不要传递该参数。

    【讨论】:

    • 你的意思是 df['Roles'].str.split(?
    • 不,而是s 是您的系列,s.str.split(r'(?&lt;=\)),\s+', expand=True)
    • 看来输出只是第一个元素,即 ABCD (Actor)
    • 你到底在执行什么?即使摆脱re 并仅使用pd.Series.str.split 运行,您也不应该得到这样的输出。 (请参阅上面的更新答案。)
    • df['Role_Split'] = df['Roles'].str.split(r'(?
    猜你喜欢
    • 1970-01-01
    • 2017-08-24
    • 2020-07-03
    • 2018-04-14
    • 2010-11-08
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    相关资源
    最近更新 更多