【问题标题】:how to split dataframe cells using delimiter into different dataframes. with conditions如何使用分隔符将数据框单元格拆分为不同的数据框。有条件
【发布时间】:2021-06-03 21:27:00
【问题描述】:

关于同一主题还有其他问题,它们有所帮助,但我有一个额外的转折。

我有一个数据框,每个(但不是全部)单元格中有多个值。

df = pd.DataFrame({'a':["10-30-410","20-40-500","25-50"], 'b':["5-8-9","4", "99"]})
index a b
0 10-30-410 5-8-9
1 20-40-500 4
2 25-50 99

如何用破折号“-”分割每个单元格并创建三个新数据框?请注意,并非所有单元格都有多个值,在这种情况下,第二个和第三个数据帧会变为 NA 或空白(将它们视为字符串)。

所以我需要 df1 成为这些值中的第一个:

index a b
0 10 5
1 20 4
2 25 99

df2 将是:

index a b
0 30 8
1 40
2 50

df3 也是如此:

index a b
0 410 9
1 500
2

我用这个得到了 df1

df1 = df.replace(r'(\d+).*(\d+).*(\d+)+', r'\1', regex=True)

但是 df2 不太好用。我得到了第二个值,还有 4 和 99,它们应该是空白的。

df2 = df.replace(r'(\d+)-(\d+).*', r'\2', regex=True)
index a b
0 30 8
1 40 4 - should be blank
2 50 99 - should be blank

这是正确的方法吗?我很擅长正则表达式,但对组很模糊。谢谢。

【问题讨论】:

    标签: python python-3.x pandas dataframe split


    【解决方案1】:

    使用str.split + concat + stack 以更可用的格式获取数据:

    new_df = pd.concat(
        (df['a'].str.split('-', expand=True),
         df['b'].str.split('-', expand=True)),
        keys=('a', 'b'),
        axis=1
    ).stack(dropna=False).droplevel(0)
    

    new_df:

          a     b
    0    10     5
    1    30     8
    2   410     9
    0    20     4
    1    40  None
    2   500  None
    0    25    99
    1    50  None
    2  None  None
    

    n cols 的可扩展选项:

    cols = ['a', 'b']
    new_df = pd.concat(
        (df[c].str.split('-', expand=True) for c in cols),
        keys=cols,
        axis=1
    ).stack(dropna=False).droplevel(0)
    

    然后groupby level 0 + reset_index 创建数据框列表:

    dfs = [g.reset_index(drop=True) for _, g in new_df.groupby(level=0)]
    
    

    dfs:

    [    a   b
    0  10   5
    1  20   4
    2  25  99,
         a     b
    0  30     8
    1  40  None
    2  50  None,
           a     b
    0   410     9
    1   500  None
    2  None  None]
    

    完整的工作示例:

    import pandas as pd
    
    df = pd.DataFrame({
        'a': ["10-30-410", "20-40-500", "25-50"],
        'b': ["5-8-9", "4", "99"]
    })
    
    cols = ['a', 'b']
    new_df = pd.concat(
        (df[c].str.split('-', expand=True) for c in cols),
        keys=cols,
        axis=1
    ).stack(dropna=False).droplevel(0)
    
    dfs = [g.reset_index(drop=True) for _, g in new_df.groupby(level=0)]
    
    print(dfs)
    

    【讨论】:

      【解决方案2】:

      你也可以试试filter:

      k = pd.concat((df[c].str.split('-', expand=True).add_prefix(c+ '-')
                     for c in df.columns), 1).fillna('')
      df1 = k.filter(like='0')
      df2 = k.filter(like='1')
      df3 = k.filter(like='2')
      

      NOTE:要从列中删除数字,请使用:k.filter(like='0').rename(columns= lambda x: x.split('-')[0])

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-21
        • 1970-01-01
        • 1970-01-01
        • 2014-11-18
        • 1970-01-01
        • 1970-01-01
        • 2019-06-29
        • 2020-11-08
        相关资源
        最近更新 更多