【问题标题】:Splitting string multiple times and return the result as new DataFrame多次拆分字符串并将结果作为新的DataFrame返回
【发布时间】:2019-05-19 13:28:51
【问题描述】:

我正在尝试反复拆分 pandas 列。我想无限期地找到两个字符串之间的字符串。例如,假设我有来自以下输入的 pandas 列:

import numpy as np
import pandas as pd

data=np.array([["'abc'ad32kn'def'dfannasfl[]12a'ghi'"],
              ["'jk'adf%#d1asn'lm'dfas923231sassda"],
              ["'nop'ad&@*-0'qrs'd2&*@^#!!sda'tuv'dasdj_23'w'823a&@'xyz'adfa"]])

df = pd.DataFrame({'Practice Column': data.ravel()})

print(df)

然后,我想通过打开和关闭引号'...' 来拆分这些字符串,然后取出里面的内容。所以,我的最终输出是:

有人可以帮帮我吗? 谢谢。

【问题讨论】:

    标签: python regex string pandas dataframe


    【解决方案1】:

    让我们在这里使用extractall

    df['Practice Column'].str.extractall(r"'(.*?)'").unstack(1)[0].fillna('')
    
    match    0    1    2  3    4
    0      abc  def  ghi        
    1       jk   lm             
    2      nop  qrs  tuv  w  xyz
    

    模式'(.*?)' 查找单引号内的所有字符串实例。更多信息 -

    '      # Match opening quote
    (      # Open capture group
    .*?    # Non-greedy match for anything
    )      # End of capture group
    '      # Match closing quote
    

    要将其与df 合并,您可以使用join

    v = df.join(df['Practice Column']
        .str.extractall(r"'(.*?)'").unstack(1)[0].fillna(''))
    

    或者,将“练习栏”分配回去:

    v = df['Practice Column'].str.extractall(r"'(.*?)'").unstack(1)[0].fillna('')
    v.insert(0, 'Practice Column', df['Practice Column'])
    

    print(v)
    
    match                                    Practice Column    0    1    2  3    4
    a                    'abc'ad32kn'def'dfannasfl[]12a'ghi'  abc  def  ghi        
    b                     'jk'adf%#d1asn'lm'dfas923231sassda   jk   lm             
    c      'nop'ad&@*-0'qrs'd2&*@^#!!sda'tuv'dasdj_23'w'8...  nop  qrs  tuv  w  xyz
    

    另一个具有列表理解的解决方案(用于性能)。

    import re
    
    p = re.compile("'(.*?)'")    
    pd.DataFrame([
        p.findall(s) for s in df['Practice Column']]).fillna('')
    
         0    1    2  3    4
    0  abc  def  ghi        
    1   jk   lm             
    2  nop  qrs  tuv  w  xyz
    

    如果有 NaN,这将不起作用,因此这是上述解决方案的修改版本。您需要先删除 NaN。

    pd.DataFrame([
        p.findall(s) for s in df['Practice Column'].dropna()]
    ).fillna('')
    
         0    1    2  3    4
    0  abc  def  ghi        
    1   jk   lm             
    2  nop  qrs  tuv  w  xyz
    

    【讨论】:

    • 就是这样。谢谢。我不能接受它作为网站所说的不到十二分钟的解决方案,但我会尽快。你能花点时间解释一下 r"'(.*?)'"。我相信那是正则表达式。
    • @J.Dykstra 已经在答案中编辑了一些解释。
    • 这是否保留订单?例如,如果我重新合并以获取我原来的练习栏,我基本上可以将它们设置在彼此旁边吗?
    • @J.Dykstra 所得解决方案的简单性取决于您的列是否包含 NaN。这可能吗?
    • 哈哈谢谢!我的错!我不是要纠缠!祝你有美好的一天!
    猜你喜欢
    • 2019-10-19
    • 2022-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-10
    • 2017-01-07
    相关资源
    最近更新 更多