multi index python pandas multi-index

python - Marco de datos de Pandas con columna multiindex-fusionar niveles



pandas xs (4)

Existe potencialmente una forma mejor, más pirónica de aplanar las columnas de múltiples índices.

1. Usa map y únete con encabezados de columna de cadena:

grouped.columns = grouped.columns.map(''|''.join).str.strip(''|'') print(grouped)

Salida:

code colour size|sum size|average size|size size|idxmax / 0 one black 862 53.875000 16 14 1 one white 554 46.166667 12 18 2 three black 842 49.529412 17 90 3 three white 740 56.923077 13 97 4 two black 1541 61.640000 25 50 scaled_size|sum scaled_size|average scaled_size|size scaled_size|idxmax 0 6980 436.250000 16 77 1 6101 508.416667 12 13 2 7889 464.058824 17 64 3 6329 486.846154 13 73 4 12809 512.360000 25 23

2. Utilice el mapa con formato para los encabezados de columna que tienen tipos de datos numéricos.

grouped.columns = grouped.columns.map(''{0[0]}|{0[1]}''.format)

Salida:

code| colour| size|sum size|average size|size size|idxmax / 0 one black 734 52.428571 14 30 1 one white 1110 65.294118 17 88 2 three black 930 51.666667 18 3 3 three white 1140 51.818182 22 20 4 two black 656 38.588235 17 77 5 two white 704 58.666667 12 17 scaled_size|sum scaled_size|average scaled_size|size scaled_size|idxmax 0 8229 587.785714 14 57 1 8781 516.529412 17 73 2 10743 596.833333 18 21 3 10240 465.454545 22 26 4 9982 587.176471 17 16 5 6537 544.750000 12 49

3. Utilice la comprensión de lista con f-string para Pytnon 3.6+:

grouped.columns = [f''{i}|{j}'' if j != '''' else f''{i}'' for i,j in grouped.columns]

Salida:

code colour size|sum size|average size|size size|idxmax / 0 one black 1003 43.608696 23 76 1 one white 1255 59.761905 21 66 2 three black 777 45.705882 17 39 3 three white 630 52.500000 12 23 4 two black 823 54.866667 15 33 5 two white 491 40.916667 12 64 scaled_size|sum scaled_size|average scaled_size|size scaled_size|idxmax 0 12532 544.869565 23 27 1 13223 629.666667 21 13 2 8615 506.764706 17 92 3 6101 508.416667 12 43 4 7661 510.733333 15 42 5 6143 511.916667 12 49

Tengo un marco de datos, grouped , con columnas multiindex como se muestra a continuación:

import pandas as pd codes = ["one","two","three"]; colours = ["black", "white"]; textures = ["soft", "hard"]; N= 100 # length of the dataframe df = pd.DataFrame({ ''id'' : range(1,N+1), ''weeks_elapsed'' : [random.choice(range(1,25)) for i in range(1,N+1)], ''code'' : [random.choice(codes) for i in range(1,N+1)], ''colour'': [random.choice(colours) for i in range(1,N+1)], ''texture'': [random.choice(textures) for i in range(1,N+1)], ''size'': [random.randint(1,100) for i in range(1,N+1)], ''scaled_size'': [random.randint(100,1000) for i in range(1,N+1)] }, columns= [''id'', ''weeks_elapsed'', ''code'',''colour'', ''texture'', ''size'', ''scaled_size'']) grouped = df.groupby([''code'', ''colour'']).agg( {''size'': [np.sum, np.average, np.size, pd.Series.idxmax],''scaled_size'': [np.sum, np.average, np.size, pd.Series.idxmax]}).reset_index() >> grouped code colour size scaled_size sum average size idxmax sum average size idxmax 0 one black 1031 60.647059 17 81 185.153944 10.891408 17 47 1 one white 481 37.000000 13 53 204.139249 15.703019 13 53 2 three black 822 48.352941 17 6 123.269405 7.251141 17 31 3 three white 1614 57.642857 28 50 285.638337 10.201369 28 37 4 two black 523 58.111111 9 85 80.908912 8.989879 9 88 5 two white 669 41.812500 16 78 82.098870 5.131179 16 78 [6 rows x 10 columns]

¿Cómo puedo aplanar / fusionar los niveles de índice de columna como: "Nivel1 | Nivel2", por ejemplo, size|sum , scaled_size|sum . etc? Si esto no es posible, ¿hay una manera de groupby() como lo hice anteriormente sin crear columnas de múltiples índices?


No estoy seguro de si entiendo lo que quiere decir;) pero podría combinar dos columnas con datos de cadena en un índice como ese:

df[''merged_ix''] = df.code + ''|'' + df.colour df.set_index(df.merged_ix, inplace=True)


Según la respuesta de Scott Boston, poca actualización (funcionará para la columna de 2 o más niveles):

temp.columns.map(lambda x: ''|''.join([str(i) for i in x]))

¡Gracias Boston!


Siempre se podrían cambiar las columnas:

grouped.columns = [''%s%s'' % (a, ''|%s'' % b if b else '''') for a, b in grouped.columns]