Как включить столбцы в groupby, которых нет во фрейме данных Pandas

#python #pandas

#питон #панды #python #pandas

Вопрос:

Этот фрейм данных классифицируется на A и B.

и я хочу подсчитывать значения, основанные на стандартном значении «0», «> 0» и nan.

Пожалуйста, ознакомьтесь с Биографией А. Данных «nan» нет.

 df :
Category    A      A      A       B       B 
CODE       U-01   U-02   U-03    U-04    U-05
n1          0      1      0       2       nan
n2          1      1      0       nan     nan
n3          3      0      0       0       2

  

В Коде,

 df1 = (df.unstack()
         .mask(lambda x: x.gt(0), '>0')
         .fillna('nan')
         .groupby(level=[0, 2])
         .value_counts()
         .unstack([0,2], fill_value=0)
         .rename(columns={0:'0'}))
  

Выходные данные удаляют столбцы категории A и nan.
Я хочу выразить для каждого столбца в «0, > 0, nan».

 Category           A           B
Standard           0    >0     0    >0     nan 
 n1                2     1     0     1      1
 n2                1     2     0     0      2
 n3                1     1     1     1      0

  

Моя желаемая таблица вывода будет выглядеть следующим образом:

 Category                 A                   B
Standard           0    >0    nan      0    >0     nan 
 n1                2     1     0       0     1      1
 n2                1     2     0       0     0      2
 n3                1     1     0       1     1      0
  

Ответ №1:

Первая идея заключается в использовании DataFrame.reindex всех возможных комбинаций, созданных MultiIndex.from_product :

 df1 = (df.unstack()
         .mask(lambda x: x.gt(0), '>0')
         .fillna('nan')
         .groupby(level=[0, 2])
         .value_counts()
         .unstack([0,2], fill_value=0)
         .rename(columns={0:'0'})
         )

mux = pd.MultiIndex.from_product([df.columns.levels[0], ['0','>0','nan']])
df1 = df1.reindex(mux, axis=1, fill_value=0)
print (df1)
Category  A         B       
          0 >0 nan  0 >0 nan
n1        2  1   0  0  1   1
n2        1  2   0  0  0   2
n3        2  1   0  1  1   0
  

Или вы можете изменить форму с помощью stack и unstack с помощью преобразования отсутствующих значений в 0 :

 df1 = (df.unstack()
         .mask(lambda x: x.gt(0), '>0')
         .fillna('nan')
         .groupby(level=[0, 2])
         .value_counts()
         .unstack([0,2], fill_value=0)
         .rename(columns={0:'0'})
         .stack()
         .fillna(0)
         .astype(int)
         .unstack()
         )


print (df1)
Category  A         B       
          0 >0 nan  0 >0 nan
n1        2  1   0  0  1   1
n2        1  2   0  0  0   2
n3        2  1   0  1  1   0