Как замаскировать групповой кадр данных по единичной матрице - PullRequest
1 голос
/ 25 апреля 2019

Я хочу замаскировать фрейм данных, который имел групповой индекс, по единичной матрице.

Dataframe:

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

Target:

    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 Ответ

1 голос
/ 25 апреля 2019

Вы можете использовать пользовательскую функцию с отфильтрованными столбцами по длине для того же размера по маске, фильтровать по 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...