Python 聚合数据帧中的单元格/列

Python 聚合数据帧中的单元格/列,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个这样的数据帧 Index Z1 Z2 Z3 Z4 0 A(Z1W1) A(Z2W1) A(Z3W1) B(Z4W2) 1 A(Z1W3) B(Z2W1) A(Z3W2) B(Z4W3) 2 B(Z1W1) A(Z3W4) B(Z4W4) 3 B(Z1W2) 我想把它转换成 Index Z1 Z2 Z3

我有一个这样的数据帧

Index Z1       Z2       Z3       Z4  
 0    A(Z1W1)  A(Z2W1)  A(Z3W1) B(Z4W2)   
 1    A(Z1W3)  B(Z2W1)  A(Z3W2) B(Z4W3)   
 2    B(Z1W1)           A(Z3W4) B(Z4W4)
 3    B(Z1W2)
我想把它转换成

Index   Z1              Z2        Z3                    Z4
 0      A(Z1W1,Z1W3)    A(Z2W1)   A(Z3W1,Z3W2,Z3W4)     B(Z4W2,Z4W3,Z4W4)    
 1      B(Z1W1,Z1W2)    B(Z2W1)     
基本上,我想将不同单元格的值聚合到一个单元格中,如上图所示

编辑1

实际列名是两个单词或三个单词的名称,而不是A或B
例如,坚果黄油代替了

东西越来越感兴趣:-)

更新 改变


您可以使用以下方法:

  • df
    获取:

    In [194]: melted = pd.melt(df, var_name='col'); melted
    Out[194]: 
       col    value
    0   Z1  A(Z1W1)
    1   Z1  A(Z1W3)
    2   Z1  B(Z1W1)
    3   Z1  B(Z1W2)
    4   Z2  A(Z2W1)
    5   Z2  B(Z2W1)
    6   Z2         
    7   Z2         
    8   Z3  A(Z3W1)
    9   Z3  A(Z3W2)
    10  Z3  A(Z3W4)
    11  Z3         
    12  Z4  B(Z4W2)
    13  Z4  B(Z4W3)
    14  Z4  B(Z4W4)
    15  Z4         
    
  • 使用正则表达式提取
    列:

    In [195]: melted[['row','value']] = melted['value'].str.extract(r'(.*)\((.*)\)', expand=True); melted
    Out[195]: 
       col value  row
    0   Z1  Z1W1    A
    1   Z1  Z1W3    A
    2   Z1  Z1W1    B
    3   Z1  Z1W2    B
    4   Z2  Z2W1    A
    5   Z2  Z2W1    B
    6   Z2   NaN  NaN
    7   Z2   NaN  NaN
    8   Z3  Z3W1    A
    9   Z3  Z3W2    A
    10  Z3  Z3W4    A
    11  Z3   NaN  NaN
    12  Z4  Z4W2    B
    13  Z4  Z4W3    B
    14  Z4  Z4W4    B
    15  Z4   NaN  NaN
    
  • 分组,并将
    连接在一起:

    In [185]: result = melted.groupby(['col', 'row'])['value'].agg(','.join)
    In [186]: result
    Out[186]: 
    col  row
    Z1   A           Z1W1,Z1W3
         B           Z1W1,Z1W2
    Z2   A                Z2W1
         B                Z2W1
    Z3   A      Z3W1,Z3W2,Z3W4
    Z4   B      Z4W2,Z4W3,Z4W4
    Name: value, dtype: object
    
  • 值添加到
    值:

    In [188]: result['value'] = result['row'] + '(' + result['value'] + ')'
    In [189]: result
    Out[189]: 
        row              value
    col                       
    Z1    A       A(Z1W1,Z1W3)
    Z1    B       B(Z1W1,Z1W2)
    Z2    A            A(Z2W1)
    Z2    B            B(Z2W1)
    Z3    A  A(Z3W1,Z3W2,Z3W4)
    Z4    B  B(Z4W2,Z4W3,Z4W4)
    
  • 使用
    groupby/cumcount
    值覆盖
    列值,以设置即将到来的数据透视:

    In [191]: result['row'] = result.groupby(level='col').cumcount()
    In [192]: result
    Out[192]: 
         row              value
    col                        
    Z1     0       A(Z1W1,Z1W3)
    Z1     1       B(Z1W1,Z1W2)
    Z2     0            A(Z2W1)
    Z2     1            B(Z2W1)
    Z3     0  A(Z3W1,Z3W2,Z3W4)
    Z4     0  B(Z4W2,Z4W3,Z4W4)
    
  • 旋转会产生所需的结果:

    result = result.pivot(index='row', columns='col', values='value')
    

屈服

col            Z1       Z2                 Z3                 Z4
row                                                             
0    A(Z1W1,Z1W3)  A(Z2W1)  A(Z3W1,Z3W2,Z3W4)  B(Z4W2,Z4W3,Z4W4)
1    B(Z1W1,Z1W2)  B(Z2W1)                NaN                NaN
基因观念:

  • 拆分字符串值
  • 重新组合并连接stings
  • 适用于所有列

  • 更新1

    #我不得不将参数添加为_index=False到groupby(0)
    #获得与请求完全相同的输出
    
    让我们试试一列

    def str_重组:
    返回s.str.extract(r“(\w)\(.+)\”,expand=True)。groupby(0,as\u index=False)。应用(
    lambda x:'{}({})'.format(x.name','.join(x[1]))
    stru重组(df1.Z1)
    
    输出

    aa(Z1W1,Z1W3)
    B(Z1W1,Z1W2)
    
    然后应用于所有列

    df.apply(str_重组)
    
    输出

    z1z2z3z4
    0A(Z1W1,Z1W3)A(Z2W1)A(Z3W1,Z3W2,Z3W4)B(Z4W2,Z4W3,Z4W4)
    1b(Z1W1,Z1W2)B(Z2W1)
    

    更新2
    在100000个样本行上的性能

    • 928 ms对于此
      应用
      版本;b
    • 1.55秒对于@Wen编写的
      stack()

    您有多少行?这些行是动态的,它们不固定。我收到此错误。您可以帮助处理此序列项0:预期的str实例,在执行v=line@Rookie_123将所有空白替换为np。nanMy实际数据由非单个单词的名称组成,例如它有坚果黄油(z1W1)和坚果黄油(z1w2)当我在括号中执行第二个字母时,有些甚至是3个单词的名称,例如Nut(Butter)同样,对于所有其他问题,现在的答案变得更加有趣:)谢谢你的帮助,我通过函数学习了一种新的解决方法,再次感谢你的帮助,一种解决同一问题的新方法,像你这样的人让Stackoverflow非常棒:)
    In [191]: result['row'] = result.groupby(level='col').cumcount()
    In [192]: result
    Out[192]: 
         row              value
    col                        
    Z1     0       A(Z1W1,Z1W3)
    Z1     1       B(Z1W1,Z1W2)
    Z2     0            A(Z2W1)
    Z2     1            B(Z2W1)
    Z3     0  A(Z3W1,Z3W2,Z3W4)
    Z4     0  B(Z4W2,Z4W3,Z4W4)
    
    result = result.pivot(index='row', columns='col', values='value')
    
    import pandas as pd
    df = pd.DataFrame({
     'Z1': ['A(Z1W1)', 'A(Z1W3)', 'B(Z1W1)', 'B(Z1W2)'],
     'Z2': ['A(Z2W1)', 'B(Z2W1)', '', ''],
     'Z3': ['A(Z3W1)', 'A(Z3W2)', 'A(Z3W4)', ''],
     'Z4': ['B(Z4W2)', 'B(Z4W3)', 'B(Z4W4)', '']}, index=[0, 1, 2, 3],)
    
    melted = pd.melt(df, var_name='col').dropna()
    melted[['row','value']] = melted['value'].str.extract(r'(.*)\((.*)\)', expand=True)
    result = melted.groupby(['col', 'row'])['value'].agg(','.join)
    result = result.reset_index('row')
    result['value'] = result['row'] + '(' + result['value'] + ')'
    result['row'] = result.groupby(level='col').cumcount()
    result = result.reset_index()
    result = result.pivot(index='row', columns='col', values='value')
    print(result)
    
    col            Z1       Z2                 Z3                 Z4
    row                                                             
    0    A(Z1W1,Z1W3)  A(Z2W1)  A(Z3W1,Z3W2,Z3W4)  B(Z4W2,Z4W3,Z4W4)
    1    B(Z1W1,Z1W2)  B(Z2W1)                NaN                NaN