如何在熊猫中拆分没有给定分隔符的字符串

Posted

技术标签:

【中文标题】如何在熊猫中拆分没有给定分隔符的字符串【英文标题】: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 【参考方案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:] 作为拆分。好吧,我不确定正则表达式中的格式是否总是如此。我在问题中没有看到足够的信息来决定这个

以上是关于如何在熊猫中拆分没有给定分隔符的字符串的主要内容,如果未能解决你的问题,请参考以下文章

拆分(分解)熊猫数据框字符串条目以分隔行

如何通过分隔符将字符串拆分为数组?

当出现任何给定的分隔符时拆分 JavaScript 字符串 [重复]

如何使用分隔符数组在 Java 中使用多个分隔符拆分字符串? [复制]

如何在熊猫数据框中捕获连字符分隔数字的平均值?

在C中使用多个分隔符拆分字符串[重复]