python - aggfunc - pivot_table margins
Pandas: Diferencia entre pivot y pivot_table. ¿Por qué solo funciona pivot_table? (6)
Tengo el siguiente marco de datos.
df.head(30)
struct_id resNum score_type_name score_value
0 4294967297 1 omega 0.064840
1 4294967297 1 fa_dun 2.185618
2 4294967297 1 fa_dun_dev 0.000027
3 4294967297 1 fa_dun_semi 2.185591
4 4294967297 1 ref -1.191180
5 4294967297 2 rama -0.795161
6 4294967297 2 omega 0.222345
7 4294967297 2 fa_dun 1.378923
8 4294967297 2 fa_dun_dev 0.028560
9 4294967297 2 fa_dun_rot 1.350362
10 4294967297 2 p_aa_pp -0.442467
11 4294967297 2 ref 0.249477
12 4294967297 3 rama 0.267443
13 4294967297 3 omega 0.005106
14 4294967297 3 fa_dun 0.020352
15 4294967297 3 fa_dun_dev 0.025507
16 4294967297 3 fa_dun_rot -0.005156
17 4294967297 3 p_aa_pp -0.096847
18 4294967297 3 ref 0.979644
19 4294967297 4 rama -1.403292
20 4294967297 4 omega 0.212160
21 4294967297 4 fa_dun 4.218029
22 4294967297 4 fa_dun_dev 0.003712
23 4294967297 4 fa_dun_semi 4.214317
24 4294967297 4 p_aa_pp -0.462765
25 4294967297 4 ref -1.960940
26 4294967297 5 rama -0.600053
27 4294967297 5 omega 0.061867
28 4294967297 5 fa_dun 3.663050
29 4294967297 5 fa_dun_dev 0.004953
De acuerdo con la documentación de pivote, debería poder remodelar esto en el score_type_name usando la función de pivote.
df.pivot(columns=''score_type_name'',values=''score_value'',index=[''struct_id'',''resNum''])
Pero, me sale lo siguiente.
Sin embargo, la función pivot_table parece funcionar:
pivoted = df.pivot_table(columns=''score_type_name'',
values=''score_value'',
index=[''struct_id'',''resNum''])
Pero no se presta, al menos para mí, a un análisis más profundo. Quiero que tenga solo el struct_id, resNum y score_type_name como columnas en lugar de apilar el score_type_name encima de las otras columnas. Además, quiero que el struct_id sea para cada fila y no se agregue en una fila unida como lo hace para la tabla.
Entonces, ¿alguien puede decirme cómo puedo obtener un buen Dataframe como quiero usar pivot? Además, a partir de la documentación, no puedo decir por qué funciona pivot_table y pivot no. Si veo el primer ejemplo de pivote, parece exactamente lo que necesito.
PD: publiqué una pregunta en referencia a este problema, pero hice un trabajo muy pobre al demostrar el resultado, lo eliminé y lo intenté nuevamente usando el portátil ipython. Me disculpo de antemano si está viendo esto dos veces.
Aquí está el cuaderno para su referencia completa
EDITAR - Mis resultados deseados se verían así (hechos en Excel):
StructId resNum pdb_residue_number chain_id name3 fa_dun fa_dun_dev fa_dun_rot fa_dun_semi omega p_aa_pp rama ref
4294967297 1 99 A ASN 2.1856 0.0000 2.1856 0.0648 -1.1912
4294967297 2 100 A MET 1.3789 0.0286 1.3504 0.2223 -0.4425 -0.7952 0.2495
4294967297 3 101 A VAL 0.0204 0.0255 -0.0052 0.0051 -0.0968 0.2674 0.9796
4294967297 4 102 A GLU 4.2180 0.0037 4.2143 0.2122 -0.4628 -1.4033 -1.9609
4294967297 5 103 A GLN 3.6630 0.0050 3.6581 0.0619 -0.2759 -0.6001 -1.5172
4294967297 6 104 A MET 1.5175 0.2206 1.2968 0.0504 -0.3758 -0.7419 0.2495
4294967297 7 105 A HIS 3.6987 0.0184 3.6804 0.0547 0.4019 -0.1489 0.3883
4294967297 8 106 A THR 0.1048 0.0134 0.0914 0.0003 -0.7963 -0.4033 0.2013
4294967297 9 107 A ASP 2.3626 0.0005 2.3620 0.0521 0.1955 -0.3499 -1.6300
4294967297 10 108 A ILE 1.8447 0.0270 1.8176 0.0971 0.1676 -0.4071 1.0806
4294967297 11 109 A ILE 0.1276 0.0092 0.1183 0.0208 -0.4026 -0.0075 1.0806
4294967297 12 110 A SER 0.2921 0.0342 0.2578 0.0342 -0.2426 -1.3930 0.1654
4294967297 13 111 A LEU 0.6483 0.0019 0.6464 0.0845 -0.3565 -0.2356 0.7611
4294967297 14 112 A TRP 2.5965 0.1507 2.4457 0.5143 -0.1370 -0.5373 1.2341
4294967297 15 113 A ASP 2.6448 0.1593 0.0510 -0.5011
El fragmento de código dado puede ayudarlo a aplanar aún más el aspecto de su marco de datos.
df.set_index([''struct_id'',''resNum'',''score_type_name'']).unstack().reset_index()
df.loc[:,[''struct_id'',''resNum'',''fa_dun'',''fa_dun_dev'',''fa_dun_rot'']]
Lo depuré un poco.
- El DataFrame.pivot () y el DataFrame.pivot_table () son diferentes.
- pivot () no acepta una lista para el índice.
- pivot_table () acepta.
Internamente, ambos usan reset_index () / stack () / unstack () para hacer el trabajo.
pivot () es solo un atajo para un uso simple, creo.
No estoy seguro de entender, pero lo intentaré. Usualmente uso stack / unstack en lugar de pivote, ¿está esto más cerca de lo que quieres?
df.set_index([''struct_id'',''resNum'',''score_type_name'']).unstack()
score_value
score_type_name fa_dun fa_dun_dev fa_dun_rot fa_dun_semi omega
struct_id resNum
4294967297 1 2.185618 0.000027 NaN 2.185591 0.064840
2 1.378923 0.028560 1.350362 NaN 0.222345
3 0.020352 0.025507 -0.005156 NaN 0.005106
4 4.218029 0.003712 NaN 4.214317 0.212160
5 3.663050 0.004953 NaN NaN 0.061867
score_type_name p_aa_pp rama ref
struct_id resNum
4294967297 1 NaN NaN -1.191180
2 -0.442467 -0.795161 0.249477
3 -0.096847 0.267443 0.979644
4 -0.462765 -1.403292 -1.960940
5 NaN -0.600053 NaN
No estoy seguro de por qué su pivote no está funcionando (me parece que debería, pero podría estar equivocado), pero parece funcionar (o al menos no dar un error) si dejo ''struct_id'' . Por supuesto, esa no es realmente una solución útil para el conjunto de datos completo donde tiene más de un valor diferente para ''struct_id''.
df.pivot(columns=''score_type_name'',values=''score_value'',index=''resNum'')
score_type_name fa_dun fa_dun_dev fa_dun_rot fa_dun_semi omega
resNum
1 2.185618 0.000027 NaN 2.185591 0.064840
2 1.378923 0.028560 1.350362 NaN 0.222345
3 0.020352 0.025507 -0.005156 NaN 0.005106
4 4.218029 0.003712 NaN 4.214317 0.212160
5 3.663050 0.004953 NaN NaN 0.061867
score_type_name p_aa_pp rama ref
resNum
1 NaN NaN -1.191180
2 -0.442467 -0.795161 0.249477
3 -0.096847 0.267443 0.979644
4 -0.462765 -1.403292 -1.960940
5 NaN -0.600053 NaN
Editar para agregar: reset_index()
se convertirá de un multi-índice (jerárquico) a un estilo más plano. Todavía hay una cierta jerarquía en los nombres de las columnas, a veces la forma más fácil de deshacerse de ellos es hacer df.columns=[''var1'',''var2'',...]
aunque hay formas más sofisticadas si haces algunas buscando.
df.set_index([''struct_id'',''resNum'',''score_type_name'']).unstack().reset_index()
struct_id resNum score_value
score_type_name fa_dun fa_dun_dev fa_dun_rot
0 4294967297 1 2.185618 0.000027 NaN
1 4294967297 2 1.378923 0.028560 1.350362
2 4294967297 3 0.020352 0.025507 -0.005156
3 4294967297 4 4.218029 0.003712 NaN
4 4294967297 5 3.663050 0.004953 NaN
Otra advertencia:
pivot_table
solo permitirá tipos numéricos como "valores =", mientras que pivot
tomará tipos de cadena como "valores =".
Para cualquier persona que todavía esté interesada en la diferencia entre pivot
y pivot_table
, existen principalmente dos diferencias:
-
pivot_table
es una generalización depivot
que puede manejar valores duplicados para un par de columna / índice pivotado . Específicamente, puede dar apivot_table
una lista de funciones de agregación usando el argumento de palabra claveaggfunc
. El carácter predeterminado predeterminado depivot_table
esnumpy.mean
. -
pivot_table
también admite el uso de varias columnas para el índice y la columna de la tabla dinámica . Se generará automáticamente un índice jerárquico para usted.
REF: pivot
y pivot_table
Para obtener el marco de datos que obtuvo de la llamada pivot_table
al formato que desea:
pivoted.columns.name=None ## remove the score_type_name
result = pivoted.reset_index() ## puts index columns back into dataframe body