【问题标题】:How to split a string without given delimeter in Panda如何在熊猫中拆分没有给定分隔符的字符串
【发布时间】:2021-07-02 22:27:46
【问题描述】:
dfcolumn = [PUEF2CarmenXFc034DpEd, PUEF2BalulanFc034CamH, CARF1BalulanFc013Baca, ...] 

我的输出应该是:

dfnewcolumn1 = [PUEF2, PUEF2 , CARF1]
dfnewcolumn2 = [CarmenXFc034DpEd, BalulanFc034CamH, BalulanFc013Baca]

【问题讨论】:

  • 好吧,是什么定义了这些字符串应该如何拆分?除非您说出条件是什么,否则即使是人类也无法拆分您的字符串
  • 我建议关闭这个问题,除非我们有足够的信息来回答它
  • 欢迎来到 Stack Overflow。请阅读如何问好questions。确保您的问题涵盖以下 3 个要素: 1. 问题陈述 2. 您的代码(应该是 Minimal, Reproducible Example 3. 错误消息(最好是完整的 Traceback 以帮助其他人查看和提供反馈)。有时可能已经提出了相同的问题. 确保您的问题不是duplicate

标签: python pandas dataframe


【解决方案1】:

关于这个紧凑的解决方案:

import pandas as pd

df = pd.DataFrame({"original": ["PUEF2CarmenXFc034DpEd", "PUEF2BalulanFc034CamH", "CARF1BalulanFc013Baca"]})
df2 = pd.DataFrame(df.original.str.split(r"(\d)", n=1).to_list(), columns=["part1", "separator", "part2"])
df2.part1 = df2.part1 + df2.separator.astype(str)
df2

   part1 separator             part2
0  PUEF2         2  CarmenXFc034DpEd
1  PUEF2         2  BalulanFc034CamH
2  CARF1         1  BalulanFc013Baca

我用:

  • Series.str.split 带有一个正则表达式模式和一个 kwarg 来指定它应该只在第一次匹配时拆分。
  • 在正则表达式模式中,我使用一个组((\d) 中的圆括号)来捕获分隔符
  • to_list() 将拆分输出为列表列表
  • DataFrame 构造函数,用于从该列表构建新的 DataFrame
  • 两列字符串拼接

【讨论】:

    【解决方案2】:

    假设您的拆分标准是固定数量的字符(例如此处为 5 个),您可以使用:

    df['dfnewcolumn1'] = df['dfcolumn'].str[:5]
    df['dfnewcolumn2'] = df['dfcolumn'].str[5:]
    

    结果:

                    dfcolumn dfnewcolumn1      dfnewcolumn2
    0  PUEF2CarmenXFc034DpEd        PUEF2  CarmenXFc034DpEd
    1  PUEF2BalulanFc034CamH        PUEF2  BalulanFc034CamH
    2  CARF1BalulanFc013Baca        CARF1  BalulanFc013Baca
    

    如果您的拆分标准是字符串中的第一个数字,您可以使用:

    df[['dfnewcolumn1', 'dfnewcolumnX']] = df['dfcolumn'].str.split(r'(?<=\d)\D', n=1, expand=True)
    df[['dfnewcolumnX', 'dfnewcolumn2']] = df['dfcolumn'].str.split(r'\D*\d', n=1, expand=True)
    df = df.drop(columns='dfnewcolumnX')
    

    使用以下修改后的原始数据和更多的测试用例:

                     dfcolumn
    0   PUEF2CarmenXFc034DpEd
    1   PUEF2BalulanFc034CamH
    2   CARF1BalulanFc013Baca
    3    CAF1BalulanFc013Baca
    4  PUEFA2BalulanFc034CamH
    

    运行代码:

    df[['dfnewcolumn1', 'dfnewcolumnX']] = df['dfcolumn'].str.split(r'(?<=\d)\D', n=1, expand=True)
    df[['dfnewcolumnX', 'dfnewcolumn2']] = df['dfcolumn'].str.split(r'\D*\d', n=1, expand=True)
    df = df.drop(columns='dfnewcolumnX')
    

    结果:

                     dfcolumn dfnewcolumn1      dfnewcolumn2
    0   PUEF2CarmenXFc034DpEd        PUEF2  CarmenXFc034DpEd
    1   PUEF2BalulanFc034CamH        PUEF2  BalulanFc034CamH
    2   CARF1BalulanFc013Baca        CARF1  BalulanFc013Baca
    3    CAF1BalulanFc013Baca         CAF1  BalulanFc013Baca
    4  PUEFA2BalulanFc034CamH       PUEFA2  BalulanFc034CamH
    

    【讨论】:

    • 谢谢你,@SeaBean。这段代码正是我需要的。
    • @Pati 那你为什么选择另一个答案?
    【解决方案3】:

    假设您的前缀由一系列字母组成,后跟一系列数字,它们的长度都是可变的。然后可以构造一个正则表达式拆分函数并将其应用于每个单元格。

    解决方案

    import pandas as pd
    import re
    
    # data
    df = pd.DataFrame()
    df["dfcolumn"] = ["PUEF2CarmenXFc034DpEd", "PUEF2BalulanFc034CamH", "CARF1BalulanFc013Baca"]
    
    def f_split(s: str):
        """Split two part by regex"""
        # alphabet(s) followed by digit(s)
        o = re.match(r"^([A-Za-z]+\d+)(.*)$", s)
        # may add exception handling here if there is no match
        return o.group(1), o.group(2)
    
    df[["dfnewcolumn1", "dfnewcolumn2"]] = df["dfcolumn"].apply(f_split).to_list()
    

    注意 .to_list() 将元组转换为列表,这是新列分配工作所必需的。

    结果

    print(df)
                    dfcolumn dfnewcolumn1      dfnewcolumn2
    0  PUEF2CarmenXFc034DpEd        PUEF2  CarmenXFc034DpEd
    1  PUEF2BalulanFc034CamH        PUEF2  BalulanFc034CamH
    2  CARF1BalulanFc013Baca        CARF1  BalulanFc013Baca
    

    【讨论】:

    • 在不知道真正需要什么的情况下,我只会将[:5], [5:] 作为拆分。好吧,我不确定正则表达式中的格式是否总是如此。我在问题中没有看到足够的信息来决定这个
    猜你喜欢
    • 2021-08-05
    • 1970-01-01
    • 2019-05-17
    • 2012-11-07
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    相关资源
    最近更新 更多