【问题标题】:Separate column data based on comma characters using pandas regex使用 pandas 正则表达式基于逗号字符分隔列数据
【发布时间】:2021-07-17 07:16:00
【问题描述】:

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

df = pd.DataFrame({'val': ['V583 ,ATTENTION, PRIMARY','Y9207,INDOOR LIVING, sEcondary',' z526, liver,primary ','12345678, test, secondary',',project,']})

我想根据comma 字符拆分/分离列val 数据。

例如,所有字符 before 1st comma 应该转到 first 列 同样,所有字符 after 1st commabefore 2nd comma 都应该转到 second 列 同样,after 2nd commabefore 3rd comma 的所有字符都应该转到 third

我尝试了以下

df['val'].astype(str).str.extract(r'\s*([a-zA-Z0-9\s]*)',expand=True)

我希望我的输出如下所示

【问题讨论】:

    标签: python regex pandas dataframe series


    【解决方案1】:

    Series.str.extractall

    我们可以extract所有出现的捕获组指定为正则表达式模式,然后unstack进行重塑。

    df['val'].str.extractall(r'([^,]+)(?:\s*,\s*|$)')[0].unstack()
    

    match         0              1          2
    0         V583       ATTENTION    PRIMARY
    1         Y9207  INDOOR LIVING  sEcondary
    2          z526          liver   primary 
    3      12345678           test  secondary
    4       project            NaN        NaN
    

    正则表达式详细信息:

    • ([^,]+) : 第一个捕获组
      • [^,]+ :匹配列表中不存在的任何字符[,] 一次或多次。
    • (?:\s*,\s*|$) : 非捕获组
      • \s*,\s* : 第一种选择
        • \s* :匹配任何空白字符零次或多次
        • , :字面匹配字符逗号
        • \s* :匹配任何空白字符零次或多次
      • $ :第二个替代方案在行尾断言位置

    PS:如果您有任意数量的逗号分隔字符串,此方法也可以工作。

    【讨论】:

    • 谢谢,赞成.. 将其标记为具有普遍性和详细解释的解决方案
    • @TheGreat Happy coding!
    【解决方案2】:

    使用您展示的示例,请尝试以下操作。在这里使用 Pandas 的extract 功能。简单的解释是:在提取中提到正则表达式以在 DataFrame 中创建 3 个新列。它基本上根据显示的示例为每个新字段创建 3 个捕获组。

    df[["first", "second", "third"]] =  df['val'].str.extract(r'^([^,]*),([^,]*),(.*)$',expand=True)
    

    Here is online demo of above regex

    df 的输出如下:

                                  val     first         second       third
    0        V583 ,ATTENTION, PRIMARY     V583       ATTENTION     PRIMARY
    1  Y9207,INDOOR LIVING, sEcondary     Y9207  INDOOR LIVING   sEcondary
    2            z526, liver,primary       z526          liver    primary 
    3       12345678, test, secondary  12345678           test   secondary
    4                       ,project,                  project            
    

    【讨论】:

    • @TheGreat,哦,你展示的样本对我来说效果很好。如果您的实际 df 与显示的 df 相同,请告诉我?
    • 是的,它与示例 df 相同...不知道为什么我会在原始数据中获得额外的列。但是是的,它在示例数据中工作正常
    • @TheGreat,您的实际数据中可能有更多逗号吗?如果是,那么尝试将我的解决方案更改为 df[["first", "second", "third"]] = df['val'].str.extract(r'^([^,]*),([^,]*),([^,]*)',expand=True) 一次,这只会捕获第三个逗号之前的值。让我知道进展如何,干杯。
    【解决方案3】:

    您可以在这里使用str.extract,如下所示:

    df["first"] = df["val"].str.extract(r'^\s*(.*?)\s*,')
    df["second"] = df["val"].str.extract(r',\s*(.*?)\s*,')
    df["third"] = df["val"].str.extract(r',\s*([^,]*)$')
    

    【讨论】:

      【解决方案4】:

      使用str.split(expand=True)

        df.join(df['val'].str.split(',', expand=True).rename(columns={0:'first',1:'second',2:'third'}))
      
                                    val     first         second       third
      0        V583 ,ATTENTION, PRIMARY     V583       ATTENTION     PRIMARY
      1  Y9207,INDOOR LIVING, sEcondary     Y9207  INDOOR LIVING   sEcondary
      2            z526, liver,primary       z526          liver    primary 
      3       12345678, test, secondary  12345678           test   secondary
      4                       ,project,                  project            
      

      【讨论】:

      • 但我得到额外的列,标题为456,值为None
      • 你有额外的昏迷。你可以把多余的列切掉df1.iloc[:,:4]
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多