【问题标题】:How can I split Pandas dataframe column with strings according to multiple conditions如何根据多个条件用字符串拆分 Pandas 数据框列
【发布时间】:2021-07-21 01:40:57
【问题描述】:

我有一个如下所示的 pandas 数据框:

    ID       Col.A

28654      This is a dark chocolate which is sweet 
39876      Sky is blue 1234 Sky is cloudy 3423
88776      Stars can be seen in the dark sky
35491      Schools are closed 4568 but shops are open

我试图在 darkdigits 之前拆分 Col.A。我想要的结果如下所示。

     ID             Col.A                             Col.B
    
    28654      This is a                  dark chocolate which is sweet 
    39876      Sky is blue                1234 Sky is cloudy 3423
    88776      Stars can be seen in the   dark sky
    35491      Schools are closed         4568 but shops are open

我尝试将包含单词dark 的行分组到一个数据帧,并将带有数字的行分组到另一个数据帧,然后相应地拆分它们。之后,我可以连接生成的数据帧以获得预期的结果。代码如下:

df = pd.DataFrame({'ID':[28654,39876,88776,35491], 'Col.A':['This is a dark chocolate which is sweet', 
                                                            'Sky is blue 1234 Sky is cloudy 3423', 
                                                            'Stars can be seen in the dark sky',
                                                            'Schools are closed 4568 but shops are open']})

df1 = df[df['Col.A'].str.contains(' dark ')==True]
df2 = df.merge(df1,indicator = True, how='left').loc[lambda x : x['_merge']!='both']
df1 = df1["Col.A"].str.split(' dark ', expand = True)
df2 = df2["Col.A"].str.split('\d+', expand = True)
pd.concat([[df1, df2], axis =0)

得到的结果与预期的不同。也就是说,

      0                              1
0   This is a                   chocolate which is sweet
2   Stars can be seen in the     sky    
1   Sky is blue                  Sky is cloudy  
3   Schools are closed           but shops are open

我错过了字符串中的数字和结果中的单词dark

那么我怎样才能解决这个问题并在不丢失拆分单词和数字的情况下获得结果呢?

有没有办法“在预期的单词或数字之前切片”而不删除它们?

【问题讨论】:

    标签: python regex pandas dataframe


    【解决方案1】:
    df[["Col.A", "Col.B"]] = df["Col.A"].str.split(
        r"\s*(dark.*|\d.*)", n=1, expand=True
    )[[0, 1]]
    print(df)
    

    打印:

          ID                     Col.A                          Col.B
    0  28654                 This is a  dark chocolate which is sweet
    1  39876               Sky is blue        1234 Sky is cloudy 3423
    2  88776  Stars can be seen in the                       dark sky
    3  35491        Schools are closed        4568 but shops are open
    

    【讨论】:

      【解决方案2】:

      Series.str.split

      s = df['Col.A'].str.split(r'\s+(?=\b(?:dark|\d+)\b)', n=1, expand=True)
      df[['ID']].join(s.set_axis(['Col.A', 'Col.B'], 1))
      

            ID                     Col.A                          Col.B
      0  28654                 This is a  dark chocolate which is sweet
      1  39876               Sky is blue        1234 Sky is cloudy 3423
      2  88776  Stars can be seen in the                       dark sky
      3  35491        Schools are closed        4568 but shops are open
      

      正则表达式详细信息:

      • \s+ :匹配任何空白字符一次或多次
      • (?=\b(?:dark|\d+)\b) : 积极前瞻
        • \b :防止部分匹配的单词边界
        • (?:dark|\d+): 非捕获组
          • dark : First Alternative 匹配暗字符
          • \d+ :第二种选择,匹配任何数字一次或多次
        • \b :防止部分匹配的字边界

      在线查看regex demo

      【讨论】:

      • 这很酷。如果我在同一行中有darkdarkest 并且我只需要在dark 之前拆分怎么办?有什么办法吗?
      • @AthulRT 是的,我们可以这样做。我已经编辑了答案。
      【解决方案3】:

      使用您展示的示例,请尝试以下操作。使用 Pandas 的str.extract 功能。简单的解释是使用提取函数并提及正​​则表达式来创建具有非贪婪匹配的第一个捕获组,并且第二个组具有数字或深色字符串,直到行的最后一行并将其保存到 Col.A 和 Col.B 列中。

      df[["Col.A","Col.B"]] = df['Col.A'].str.extract(r'(.*?)((?:dark|\d+).*)', expand=True)
      df
      

      显示示例输出如下:

          ID      Col.A                       Col.B
      0   28654   This is a                   dark chocolate which is sweet
      1   39876   Sky is blue                 1234 Sky is cloudy 3423
      2   88776   Stars can be seen in the    dark sky
      3   35491   Schools are closed          4568 but shops are open
      

      【讨论】:

        猜你喜欢
        • 2022-08-16
        • 1970-01-01
        • 1970-01-01
        • 2020-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多