Pandas 通过多个分隔符将一列拆分为同一列

Pandas Split a Column by Multiple delimiters into same column

我有一个 pandas 多列数据框。但感兴趣的专栏说的是 Col A,它看起来像:

      dfInput

               A 

       12 - ksjksu,nsusi,9018,1.00uy,9.0Vm,+/ - 20%(0.22suns); 891- 1o19jsksuisolslskosBN
       205 - lksiosslsoujhs%ysus(0.33mismsn);31 - jsks,msnu
       22 - 0204 - 2762.0uhsyuskis;14 - gnshj,msuis,lsolso2.2n; 67181 - iuwuwiwi

所以我的目标是将字符串分成两部分,一个是第一个 '-' before/after 分号,然后是其余部分,其中第一列将包含第一个 ' 左侧的所有数字-' 然后另一列将休息。所以我的输出数据框应该是这样的:

        **dfOutDesired**

           B                                          C
         12 891    ksjksu,nsusi,9018,1.00uy,9.0Vm,+/ - 20%(0.22suns) 1o19jsksuisolslskosBN
         205 31    lksiosslsoujhs%ysus(0.33mismsn)  jsks,msnu
         22 14 67181  0204 - 2762.0uhsyuskis gnshj,msuis,lsolso2.2n iuwuwiwi

所以到目前为止,我已经根据我之前看到的帖子尝试了以下方法:

      df['C'] =    df["A"].str.replace(r'\w+\s*-\s*', '', regex=True)

      df['A'] = df['A'].str.replace(' ', '')
      df['A'] = df['A'].str.replace('-', ' - ')

      df["B"] = df["A"].str.replace(r'\s*;\s*\S+;+\S+;+\s*', ' ', regex=True).str.strip()

所以我得到了 Col C 的部分正确输出(其中第三行的 0204 没有被拾取),但是对于 Col B,我得到了相同的 Col A,如下所示:

       **mydfWrong**

                                B     
       12 - ksjksu,nsusi,9018,1.00uy,9.0Vm,+/ - 20%(0.22suns); 891- 1o19jsksuisolslskosBN
       205 - lksiosslsoujhs%ysus(0.33mismsn);31 - jsks,msnu
       22 - 0204 - 2762.0uhsyuskis;14 - gnshj,msuis,lsolso2.2n; 67181 - iuwuwiwi

                               C

            ksjksu,nsusi,9018,1.00uy,9.0Vm,+/ - 20%(0.22suns) 1o19jsksuisolslskosBN
            lksiosslsoujhs%ysus(0.33mismsn)  jsks,msnu
            2762.0uhsyuskis gnshj,msuis,lsolso2.2n iuwuwiwi
          

不确定在这种情况下如何正确使用正则表达式。因此,我们将不胜感激任何帮助。提前致谢。

您可以使用类似以下的方法来做到这一点。

get_nums 函数在 ; 上拆分,然后根据指定条件删除整数

get_the_rest 函数做相反的事情,用空格替换这些值

def get_nums(x):
    return " ".join([re.search(r'^[0-9]+', y.strip()).group() for y in x.split(";")])

def get_the_rest(x):
    return "".join([re.sub(r'[0-9]+\s?\-', '', y.strip()) for y in x.split(";")])

df["B"] = df["A"].apply(lambda x: get_nums(x))
df["C"] = df["A"].apply(lambda x: get_the_rest(x))

您可以使用单个正则表达式调用 findall,然后只获取必要的数据:

import pandas as pd
df = pd.DataFrame({'A': ['205 - lksiosslsoujhs%ysus(0.33mismsn);31 - jsks,msnu', '22 - 0204 - 2762.0uhsyuskis;14 - gnshj,msuis,lsolso2.2n; 67181 - iuwuwiwi']})

rx = r'(\d+)\s*-\s*(.*?)(?=;\s*\d|$)' # Define the regex
m = df['A'].str.findall(rx)         # Get all matches and captures
df["B"] = m.apply(lambda x: " ".join(c[0] for c in x)) # Join Group 1 values into Column B
df["C"] = m.apply(lambda x: " ".join(c[1] for c in x)) # Join Group 1 values into Column C

输出:

>>> print(df.to_string())
                                                                            A            B                                                       C
0                       205 - lksiosslsoujhs%ysus(0.33mismsn);31 - jsks,msnu       205 31               lksiosslsoujhs%ysus(0.33mismsn) jsks,msnu
1  22 - 0204 - 2762.0uhsyuskis;14 - gnshj,msuis,lsolso2.2n; 67181 - iuwuwiwi  22 14 67181  0204 - 2762.0uhsyuskis gnshj,msuis,lsolso2.2n iuwuwiwi

查看匹配

regex demo
  • (\d+) - 第 1 组:一个或多个数字
  • \s*-\s* - 包含零个或多个空格的 -
  • (.*?) - 第 2 组:除换行字符外的任何零个或多个字符尽可能少
  • (?=;\s*\d|$) - 匹配紧跟 ; + 零个或多个空格然后是数字或字符串结尾的位置的正向前瞻。