【问题标题】:Convert cells in dataframe with multiple values to multiple rows将数据框中具有多个值的单元格转换为多行
【发布时间】:2018-09-16 14:29:16
【问题描述】:

我的数据是这样的:

Name    test1     test2      Count
Emp1    X,Y        A           1
Emp2    X          A,B,C       2
Emp3    Z          C           3

我正在使用下面的代码将具有多个值的 test1 单元格拆分为单独的行。但是,我不确定如何拆分 Test2 列。

df2 = df.test1.str.split(',').apply(pd.Series)
df2.index = df.set_index(['Name', 'count']).index
df2.stack().reset_index(['Name', 'count'])
df2

输出是:

Name    test1   Count
Emp1    X        1
Emp1    Y        1
Emp2    X        2
Emp2    X        2
Emp2    X        2
Emp2    Z        3

我正在尝试拆分 test1test2 以便实现以下输出:

Name    test1    test2  Count
Emp1    X          A      1
Emp1    Y          A      1
Emp2    X          A      2
Emp2    X          B      2
Emp2    X          C      2
Emp2    Z          C      3

有人可以帮忙吗?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    我只是修复你的代码,因为我不推荐你取消嵌套数据框的方法,你可以在这里查看answer,有多种不错的方法。

    df2 = df.test1.str.split(',').apply(pd.Series)
    df2.index = df.set_index(['Name', 'Count']).index
    df2=df2.stack().reset_index(['Name', 'Count'])
    df3 = df.test2.str.split(',').apply(pd.Series)
    df3.index = df.set_index(['Name', 'Count']).index
    df3=df3.stack().reset_index(['Name', 'Count'])
    

    只需在此处输入merge

    df2.merge(df3,on=['Name', 'Count'],how='outer')
    Out[132]: 
       Name  Count 0_x 0_y
    0  Emp1      1   X   A
    1  Emp1      1   Y   A
    2  Emp2      2   X   A
    3  Emp2      2   X   B
    4  Emp2      2   X   C
    5  Emp3      3   Z   C
    

    【讨论】:

    • @Mahesh 我试图使我的解决方案尽可能通用。稍后看看,看看是否有帮助;)
    • @RafaelC 我尝试了您建议的 expand_all 函数,我观察到它正在扩展已经扩展的列。 .这会导致值重复
    【解决方案2】:

    我不认为让this answer highlighted by @wen 适应这个问题有那么简单,所以我会提出一个解决方案。

    您可以创建一个函数,该函数接受 df、要扩展的列和该列的分隔符,并根据需要多次链式调用。

    def expand(df, col, sep=','):
        r = df[col].str.split(sep)
        d = {c: df[c].values.repeat(r.str.len(), axis=0) for c in df.columns}
        d[col] = [i for sub in r for i in sub]
        return pd.DataFrame(d)
    
    expand(expand(df, 'test1'), 'test2')
    
        Name    test1   test2   Count
    0   Emp1    X       A       1
    1   Emp1    Y       A       1
    2   Emp2    X       A       2
    3   Emp2    X       B       2
    4   Emp2    X       C       2
    5   Emp3    Z       C       3
    

    假设你有一个

    df['test3'] = ['X1|X2|X3', 'X4', 'X5']
    

    这样

    >>> print(df)
    
        Name    test1   test2   Count   test3
    0   Emp1    X,Y     A       1       X1|X2|X3
    1   Emp2    X       A,B,C   2       X4
    2   Emp3    Z       C       3       X5
    

    那么,

    >>> expand(df,'test3', '|')
    
        Name    test1   test2   Count   test3
    0   Emp1    X,Y     A       1       X1
    1   Emp1    X,Y     A       1       X2
    2   Emp1    X,Y     A       1       X3
    3   Emp2    X       A,B,C   2       X4
    4   Emp3    Z       C       3       X5
    

    如果您认为列大小可能会大幅增加,您可以定义一个函数expand_all 以避免出现expand(expand(expand(expand(........)))))) 之类的东西。例如:

    def expand_all(df, cols, seps):
        ret = df
        for c,s in zip(cols,seps): ret = expand(ret,c,s)
        return ret
    
    >>> expand_all(df, ['test1', 'test2', 'test3'], [',', ',', '|'])
    
        Name    test1   test2   Count   test3
    0   Emp1    X       A       1       X1
    1   Emp1    X       A       1       X2
    2   Emp1    X       A       1       X3
    3   Emp1    Y       A       1       X1
    4   Emp1    Y       A       1       X2
    5   Emp1    Y       A       1       X3
    6   Emp2    X       A       2       X4
    7   Emp2    X       B       2       X4
    8   Emp2    X       C       2       X4
    9   Emp3    Z       C       3       X5
    

    或者无论多么合适;)


    详情:

    >>> expand(df, 'test1')
    
        Name    test1   test2   Count
    0   Emp1    X       A       1
    1   Emp1    Y       A       1
    2   Emp2    X       A,B,C   2
    3   Emp3    Z       C       3
    
    >>> expand(df, 'test2')
    
        Name    test1   test2   Count
    0   Emp1    X,Y     A       1
    1   Emp2    X       A       2
    2   Emp2    X       B       2
    3   Emp2    X       C       2
    4   Emp3    Z       C       3
    
    >>> expand(expand(df, 'test2'), 'test1') 
    
        Name    test1   test2   Count
    0   Emp1    X       A       1
    1   Emp1    Y       A       1
    2   Emp2    X       A       2
    3   Emp2    X       B       2
    4   Emp2    X       C       2
    5   Emp3    Z       C       3
    
    
    >>> expand(expand(df, 'test2'), 'test1').eq(expand(expand(df, 'test1'), 'test2')).all()
    
    Name     True
    test1    True
    test2    True
    Count    True
    dtype: bool
    

    【讨论】:

      【解决方案3】:

      理解

      pd.DataFrame(
          [(n, a, b, c)
           for n, A, B, c in zip(*map(df.get, df))
           for a in A.split(',') for b in B.split(',')],
          columns=df.columns
      )
      
         Name test1 test2  Count
      0  Emp1     X     A      1
      1  Emp1     Y     A      1
      2  Emp2     X     A      2
      3  Emp2     X     B      2
      4  Emp2     X     C      2
      5  Emp3     Z     C      3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-28
        • 1970-01-01
        • 2021-05-12
        • 1970-01-01
        • 2018-06-24
        • 2021-11-17
        相关资源
        最近更新 更多