如何通过单位矩阵掩盖分组数据帧

时间:2019-04-25 11:02:57

标签: python pandas pandas-groupby

我想按身份矩阵掩盖具有groupby索引的数据框。

数据框:

s = pd.Series([0, 1, 1, 2, 2, 2])
df = DataFrame([{'B1': '1A', 'B2': '', 'B3': '', 'U_B1': 'A', 'U_B2': '', 'U_B3': ''},
                {'B1': '3A', 'B2': '1A', 'B3': '', 'U_B1': 'A', 'U_B2': 'A', 'U_B3': ''},
                {'B1': '3A', 'B2': '1A', 'B3': '', 'U_B1': 'A', 'U_B2': 'A', 'U_B3': ''},
                {'B1': '41A', 'B2': '28A', 'B3': '3A', 'U_B1': 'A', 'U_B2': 'A', 'U_B3': 'A'},
                {'B1': '41A', 'B2': '28A', 'B3': '3A', 'U_B1': 'A', 'U_B2': 'A', 'U_B3': 'A'},
                {'B1': '41A', 'B2': '28A', 'B3': '3A', 'U_B1': 'A', 'U_B2': 'A', 'U_B3': 'A'}])

df.set_index(s)

    B1   B2   B3 U_B1 U_B2 U_B3
0   1A             A        
1   3A   1A        A    A   
1   3A   1A        A    A   
2   41A  28A  3A   A    A   A
2   41A  28A  3A   A    A   A
2   41A  28A  3A   A    A   A

目标:

    B1   B2   B3 U_B1 U_B2 U_B3
0   1A             A        
1   3A   1A        A        
1   3A   1A             A   
2   41A  28A  3A   A   
2   41A  28A  3A        A   
2   41A  28A  3A            A

和下面的代码一样,现在似乎有些问题要在组中删除''值。

df[['U_B1','U_B2','U_B3']] = df.groupby(df1.index)['U_B1','U_B2','U_B3'].apply(lambda x: x.drop(x == '')).mask(np.identity(len(x))==0)

出现错误: ValueError: Grouper and axis must be same length

我该如何处理?

如果还有其他方法也可以达到目标。


问题更新:

数据框:

df = DataFrame([{'B1': '1A', 'B2': '', 'B3': '', 'U_B1': 'A', 'U_B2': '', 'U_B3': ''},
                {'B1': '3A', 'B2': '1A', 'B3': '', 'U_B1': 'A', 'U_B2': 'A', 'U_B3': ''},
                {'B1': '41A', 'B2': '28A', 'B3': '3A', 'U_B1': 'A', 'U_B2': 'A', 'U_B3': 'A'}])

# Duplicate rows 
val = (df[['U_B1','U_B2','U_B3']] != '').sum(axis=1)
df1 = df.loc[np.repeat(val.index,val)]  
df1.index.names = ['index']
df1

    B1   B2   B3  U_B1  U_B2  U_B3
index                       
0   1A             A        
1   3A    1A       A     A  
1   3A    1A       A     A  
2   41A  28A  3A   A     A     A
2   41A  28A  3A   A     A     A
2   41A  28A  3A   A     A     A

1 个答案:

答案 0 :(得分:1)

您可以使用自定义函数,按长度将过滤后的列按掩码设置为相同的大小,按DataFrame.where进行过滤,并按DataFrame.reindex每组添加删除的列:

df1 = df.set_index(s)

def f(x):
    a = x.iloc[:, :len(x)]
    m = np.identity(len(x)).astype(bool)
    return a.where(m,'').reindex(x.columns, axis=1, fill_value='')

df1[['U_B1','U_B2','U_B3']] = (df1.groupby(df1.index)['U_B1','U_B2','U_B3'].apply(f)
                                  .reset_index(level=0, drop=True))
print (df1)
    B1   B2  B3 U_B1 U_B2 U_B3
0   1A             A          
1   3A   1A        A          
1   3A   1A             A     
2  41A  28A  3A    A          
2  41A  28A  3A         A     
2  41A  28A  3A              A