Tengo un marco de datos main_df como se muestra a continuación.

   user_id  main_code   sub_1   sub_2
0   03920   AA  YA  ZA
1   34233   BB  YB  ZA
2   02342   AA  YD  ZB
3   32324   CC  YA  ZA
4   52323   AA  YA  ZD
5   20932   DD  YD  ZD
6   02034   BB  YA  ZA

Estoy tratando de lograr un marco de datos de salida inferior. Las columnas seleccionadas (sub_1 y sub_2) de los valores únicos del marco de datos main_df cuentan y se convierten en columnas del marco de datos.

  main_code YA  YB  YD  ZA  ZB  ZD
0   AA  2.0 NaN 1.0 1.0 1.0 1.0
1   BB  1.0 1.0 NaN 2.0 NaN NaN
2   CC  1.0 NaN NaN 1.0 NaN NaN
3   DD  NaN NaN 1.0 NaN NaN 1.0

Hasta ahora lo intenté como a continuación. Tengo una salida diferente.

result_df = pd.DataFrame()
for col in ['sub_1','sub_2']:
    result_df = pd.concat([result_df, pd.DataFrame(main_df[pd.notnull(main_df[col])]['main_code'].value_counts())], axis=1)
result_df.columns = ['sub_1','sub_2']

Sería útil que alguien pueda guiarme. Gracias.

2
Akira 23 jun. 2020 a las 09:55

3 respuestas

La mejor respuesta

Utilice .melt con .pivot_table

df = df.melt(id_vars='main_code', value_vars=['sub_1', 'sub_2']).pivot_table(index='main_code', columns='value', aggfunc='count').reset_index()
3
David Erickson 23 jun. 2020 a las 07:05

Aunque la respuesta correcta ya está dada. Puede usar esto si desea seguir un enfoque personalizado.

a = (pd.pivot_table(df, index='main_code',columns= 
     ['sub_1'],aggfunc=np.count_nonzero).reset_index())

cols = a.columns.droplevel(0).to_list()

cols[0]='main_code'

a.columns=cols

print(a)
0
r-beginners 23 jun. 2020 a las 13:27

Aquí tiene:

pd.merge(
    df.pivot_table(index="main_code", columns="sub_1", aggfunc="count")["sub_2"],
    df.pivot_table(index="main_code", columns="sub_2", aggfunc="count")["sub_1"],
    left_index=True,
    right_index=True
)
0
quest 23 jun. 2020 a las 07:13