代码之家  ›  专栏  ›  技术社区  ›  Royalblue

无法使用groupby.apply添加列

  •  2
  • Royalblue  · 技术社区  · 7 年前

    最初我有下表:

    df=pd.DataFrame(
        np.arange(4*8).reshape(4,8),
        index=list('abcd'),
        columns=pd.MultiIndex.from_arrays([list('EEEETTTT'), list('XXYYZZWW'), list('rsrsrsrs')] )
    )
    
        E               T            
        X       Y       Z       W    
        r   s   r   s   r   s   r   s
    a   0   1   2   3   4   5   6   7
    b   8   9  10  11  12  13  14  15
    c  16  17  18  19  20  21  22  23
    d  24  25  26  27  28  29  30  31
    

    'V' 旁边 ( , ,'s') 多索引列如下所示:

        E                     T                  
        X          Y          W          Z       
        r   s  V   r   s  V   r   s  V   r   s  V
    a   0   1  0   2   3  0   6   7  0   4   5  0
    b   8   9  0  10  11  0  14  15  0  12  13  0
    c  16  17  0  18  19  0  22  23  0  20  21  0
    d  24  25  0  26  27  0  30  31  0  28  29  0
    

    dfl=[]
    for name, x in df.groupby(level=[0, 1], axis=1):
        index = pd.IndexSlice
        x.loc[:,index[name[0],name[1],'V']]= 0
        dfl.append(x)
    
    pd.concat(dfl, axis=1) 
    

    现在,我尝试了以下“替代”方法以获得相同的结果:

    def f(x):
        idx = pd.IndexSlice
        x.loc[:, idx[x.name[0], x.name[1], 'V']]=0
        return x
    
    df.groupby(level=[0,1], axis=1).apply(f)
    

    然而,令我惊讶的是,结果表仍然没有改变:

        E               T            
        X       Y       Z       W    
        r   s   r   s   r   s   r   s
    a   0   1   2   3   4   5   6   7
    b   8   9  10  11  12  13  14  15
    c  16  17  18  19  20  21  22  23
    d  24  25  26  27  28  29  30  31
    

    appy(func)应该允许func返回任意大小甚至标量的数据帧。

    这可能是一个错误吗?

    1 回复  |  直到 7 年前
        1
  •  2
  •   jezrael    7 年前

    它是 partial bug 与分组有关 MutiIndex in columns .

    如果与 MultiIndex in index

    您的解决方案已通过转置进行修改 索引中的多索引 ,应用函数并调回:

    def f(x):
        idx = pd.IndexSlice
        x.loc[idx[x.name[0], x.name[1], 'V'], :]=0
        x.index = x.index.droplevel([0,1])
        return x
    
    df = df.T.groupby(level=[0,1], axis=0).apply(f).T.astype(int)
    print (df)
        E                     T                  
        X          Y          W          Z       
        r   s  V   r   s  V   r   s  V   r   s  V
    a   0   1  0   2   3  0   6   7  0   4   5  0
    b   8   9  0  10  11  0  14  15  0  12  13  0
    c  16  17  0  18  19  0  22  23  0  20  21  0
    d  24  25  0  26  27  0  30  31  0  28  29  0
    

    def f(x):
        idx = pd.IndexSlice
        x.loc[idx[x.name[0], x.name[1], 'V'], :]=0
        return x
    
    df = df.T.groupby(level=[0,1], axis=0).apply(f).T.astype(int)
    print (df)
        E                     T                  
        X          Y          W          Z       
        E          E          T          T       
        X          Y          W          Z       
        r   s  V   r   s  V   r   s  V   r   s  V
    a   0   1  0   2   3  0   6   7  0   4   5  0
    b   8   9  0  10  11  0  14  15  0  12  13  0
    c  16  17  0  18  19  0  22  23  0  20  21  0
    d  24  25  0  26  27  0  30  31  0  28  29  0