Cómo hacer pivotar un dataframe
- ¿Qué es pivot?
- ¿Cómo pivotar?
- ¿Es esto un pivote?
- Formato largo a formato ancho?
He visto muchas preguntas sobre las tablas dinámicas. Incluso si no saben que están preguntando sobre tablas dinámicas, generalmente lo son. Es virtualmente imposible escribir una pregunta y respuesta canónica que abarque todos los aspectos del pivotaje....
... Pero voy a intentarlo.
El problema con la existencia preguntas y respuestas es que a menudo la pregunta se centra en un matiz que el OP tiene problemas para generalizar con el fin de utilizar un número de las buenas respuestas existentes. Sin embargo, ninguna de las respuestas intenta dar una explicación completa (porque es una tarea desalentadora)
Mira algunos ejemplos de mi búsqueda en google
-
¿Cómo pivotar un dataframe en Pandas?
- Buena pregunta y respuesta. Pero la respuesta solo responde a lo específico pregunta con poca explicación.
-
pandas pivot table to data frame
- En esta pregunta, el OP se refiere a la salida del pivote. Es decir, cómo se ven las columnas. OP quería que se viera como R. Esto no es muy útil para los usuarios de pandas.
-
pandas pivotando un dataframe, duplicar filas
- Otra pregunta decente, pero la respuesta se centra en un método, a saber
pd.DataFrame.pivot
- Otra pregunta decente, pero la respuesta se centra en un método, a saber
Así que cada vez que alguien busca pivot
obtienen resultados esporádicos que probablemente no van a responder a su pregunta específica.
Configuración
Puede notar que nombré visiblemente mis columnas y valores de columna relevantes para corresponder con cómo voy a pivotar en las respuestas a continuación. Preste atención para que se familiarice con dónde van los nombres de las columnas dónde obtener los resultados que está buscando para.
import numpy as np
import pandas as pd
from numpy.core.defchararray import add
np.random.seed([3,1415])
n = 20
cols = np.array(['key', 'row', 'item', 'col'])
arr1 = (np.random.randint(5, size=(n, 4)) // [2, 1, 2, 1]).astype(str)
df = pd.DataFrame(
add(cols, arr1), columns=cols
).join(
pd.DataFrame(np.random.rand(n, 2).round(2)).add_prefix('val')
)
print(df)
key row item col val0 val1
0 key0 row3 item1 col3 0.81 0.04
1 key1 row2 item1 col2 0.44 0.07
2 key1 row0 item1 col0 0.77 0.01
3 key0 row4 item0 col2 0.15 0.59
4 key1 row0 item2 col1 0.81 0.64
5 key1 row2 item2 col4 0.13 0.88
6 key2 row4 item1 col3 0.88 0.39
7 key1 row4 item1 col1 0.10 0.07
8 key1 row0 item2 col4 0.65 0.02
9 key1 row2 item0 col2 0.35 0.61
10 key2 row0 item2 col1 0.40 0.85
11 key2 row4 item1 col2 0.64 0.25
12 key0 row2 item2 col3 0.50 0.44
13 key0 row4 item1 col4 0.24 0.46
14 key1 row3 item2 col3 0.28 0.11
15 key0 row3 item1 col1 0.31 0.23
16 key0 row0 item2 col3 0.86 0.01
17 key0 row4 item0 col3 0.64 0.21
18 key2 row2 item2 col0 0.13 0.45
19 key0 row2 item0 col4 0.37 0.70
Pregunta(s)
¿Por qué consigo
ValueError: Index contains duplicate entries, cannot reshape
-
¿Cómo pivotar
df
de manera que los valorescol
son columnas,row
los valores son el índice, y la media deval0
son los valores?col col0 col1 col2 col3 col4 row row0 0.77 0.605 NaN 0.860 0.65 row2 0.13 NaN 0.395 0.500 0.25 row3 NaN 0.310 NaN 0.545 NaN row4 NaN 0.100 0.395 0.760 0.24
-
¿Cómo puedo pivote
df
tal quecol
los valores de las columnas,row
los valores son el índice, la media deval0
son los valores, y los valores que faltan son0
?col col0 col1 col2 col3 col4 row row0 0.77 0.605 0.000 0.860 0.65 row2 0.13 0.000 0.395 0.500 0.25 row3 0.00 0.310 0.000 0.545 0.00 row4 0.00 0.100 0.395 0.760 0.24
-
¿Puedo obtener algo que no sea
mean
, como tal vezsum
?col col0 col1 col2 col3 col4 row row0 0.77 1.21 0.00 0.86 0.65 row2 0.13 0.00 0.79 0.50 0.50 row3 0.00 0.31 0.00 1.09 0.00 row4 0.00 0.10 0.79 1.52 0.24
-
¿Puedo hacer más de una agregación a la vez?
sum mean col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4 row row0 0.77 1.21 0.00 0.86 0.65 0.77 0.605 0.000 0.860 0.65 row2 0.13 0.00 0.79 0.50 0.50 0.13 0.000 0.395 0.500 0.25 row3 0.00 0.31 0.00 1.09 0.00 0.00 0.310 0.000 0.545 0.00 row4 0.00 0.10 0.79 1.52 0.24 0.00 0.100 0.395 0.760 0.24
-
¿Puedo agregar sobre múltiples columnas de valor?
val0 val1 col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4 row row0 0.77 0.605 0.000 0.860 0.65 0.01 0.745 0.00 0.010 0.02 row2 0.13 0.000 0.395 0.500 0.25 0.45 0.000 0.34 0.440 0.79 row3 0.00 0.310 0.000 0.545 0.00 0.00 0.230 0.00 0.075 0.00 row4 0.00 0.100 0.395 0.760 0.24 0.00 0.070 0.42 0.300 0.46
-
¿Se puede subdividir por múltiples columnas?
item item0 item1 item2 col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4 row row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.605 0.86 0.65 row2 0.35 0.00 0.37 0.00 0.00 0.44 0.00 0.00 0.13 0.000 0.50 0.13 row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.000 0.28 0.00 row4 0.15 0.64 0.00 0.00 0.10 0.64 0.88 0.24 0.00 0.000 0.00 0.00
-
O
item item0 item1 item2 col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4 key row key0 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.86 0.00 row2 0.00 0.00 0.37 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.50 0.00 row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.00 0.00 0.00 row4 0.15 0.64 0.00 0.00 0.00 0.00 0.00 0.24 0.00 0.00 0.00 0.00 key1 row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.81 0.00 0.65 row2 0.35 0.00 0.00 0.00 0.00 0.44 0.00 0.00 0.00 0.00 0.00 0.13 row3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.28 0.00 row4 0.00 0.00 0.00 0.00 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 key2 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.40 0.00 0.00 row2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.13 0.00 0.00 0.00 row4 0.00 0.00 0.00 0.00 0.00 0.64 0.88 0.00 0.00 0.00 0.00 0.00
-
¿Puedo agregar la frecuencia en la que la columna y las filas ocurren juntas, también conocida como "tabulación cruzada"?
col col0 col1 col2 col3 col4 row row0 1 2 0 1 1 row2 1 0 2 1 2 row3 0 1 0 2 0 row4 0 1 2 2 1
1 answers
Empezamos por responder a la primera pregunta:{[92]]}
Pregunta 1
¿por Qué obtengo
ValueError: Index contains duplicate entries, cannot reshape
Esto ocurre porque pandas está intentando reindexar un objeto columns
o index
con entradas duplicadas. Hay varios métodos para usar que pueden realizar un pivote. Algunos de ellos no son adecuados cuando hay duplicados de las claves en las que se le pide que pivote. Por ejemplo. Consideremos pd.DataFrame.pivot
. Sé que hay entradas duplicadas que comparten los valores row
y col
:
df.duplicated(['row', 'col']).any()
True
Así que cuando yo pivot
usando
df.pivot(index='row', columns='col', values='val0')
Recibo el error mencionado anteriormente. De hecho, obtengo el mismo error cuando intento realizar la misma tarea con:
df.set_index(['row', 'col'])['val0'].unstack()
Aquí hay una lista de modismos que podemos usar para pivotar
-
pd.DataFrame.groupby
+pd.DataFrame.unstack
- Buen enfoque general para hacer casi cualquier tipo de pivote
- Se especifican todas las columnas que constituirán la niveles de fila y niveles de columna pivotados en un grupo por. A continuación, seleccione las columnas restantes que desea agregar y las funciones que desea realizar la agregación. Finalmente,
unstack
los niveles que desea que estén en el índice de la columna.
-
pd.DataFrame.pivot_table
- Una versión glorificada de
groupby
con API más intuitiva. Para muchas personas, este es el enfoque preferido. Y es el enfoque previsto por el desarrollador. - Especifique el nivel de fila, los niveles de columna, los valores que se agregarán y las funciones para realizar agregaciones.
- Una versión glorificada de
-
pd.DataFrame.set_index
+pd.DataFrame.unstack
- Conveniente e intuitivo para algunos (yo incluido). No se puede manejar claves agrupadas duplicadas.
- Similar al paradigma
groupby
, especificamos todas las columnas que eventualmente serán niveles de fila o columna y las establecemos como índice. Entoncesunstack
los niveles que queremos en las columnas. Si los niveles de índice restantes o los niveles de columna no son únicos, este método fallará.
-
pd.DataFrame.pivot
- Muy similar a
set_index
en que comparte la limitación de clave duplicada. La API también es muy limitada. Sólo toma valores escalares paraindex
,columns
,values
. - Similar al método
pivot_table
en que seleccionamos filas, columnas y valores sobre los que pivotar. Sin embargo, nosotros no se puede agregar y si las filas o columnas no son únicas, este método fallará.
- Muy similar a
-
pd.crosstab
- Esta es una versión especializada de
pivot_table
y en su forma más pura es la forma más intuitiva de realizar varias tareas.
- Esta es una versión especializada de
-
pd.factorize
+np.bincount
- Esta es una técnica muy avanzada que es muy oscura pero muy rápida. No se puede utilizar en todas las circunstancias, pero cuando se puede usar y se siente cómodo usándolo, cosechará las recompensas de rendimiento.
-
pd.get_dummies
+pd.DataFrame.dot
- Uso esto para realizar inteligentemente la tabulación cruzada.
Ejemplos
Lo que voy a hacer para cada respuesta y pregunta subsecuente es responderla usando pd.DataFrame.pivot_table
. A continuación, voy a proporcionar alternativas para realizar el la misma tarea.
Pregunta 3
¿Cómo puedo pivote
df
tal quecol
los valores de las columnas,row
los valores son el índice, la media deval0
son los valores, y los valores que faltan son0
?
-
pd.DataFrame.pivot_table
-
fill_value
no está establecido por defecto. Tiendo a configurarlo apropiadamente. En este caso lo pongo en0
. Observe que me salté pregunta 2 ya que es lo mismo que esta respuesta sin elfill_value
-
aggfunc='mean'
es el valor predeterminado y no tuve que configurarlo. Lo incluí para ser explícito.df.pivot_table( values='val0', index='row', columns='col', fill_value=0, aggfunc='mean') col col0 col1 col2 col3 col4 row row0 0.77 0.605 0.000 0.860 0.65 row2 0.13 0.000 0.395 0.500 0.25 row3 0.00 0.310 0.000 0.545 0.00 row4 0.00 0.100 0.395 0.760 0.24
-
-
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].mean().unstack(fill_value=0)
-
pd.crosstab
pd.crosstab( index=df['row'], columns=df['col'], values=df['val0'], aggfunc='mean').fillna(0)
Pregunta 4
¿Puedo obtener algo más que
mean
, como tal vezsum
?
-
pd.DataFrame.pivot_table
df.pivot_table( values='val0', index='row', columns='col', fill_value=0, aggfunc='sum') col col0 col1 col2 col3 col4 row row0 0.77 1.21 0.00 0.86 0.65 row2 0.13 0.00 0.79 0.50 0.50 row3 0.00 0.31 0.00 1.09 0.00 row4 0.00 0.10 0.79 1.52 0.24
-
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].sum().unstack(fill_value=0)
-
pd.crosstab
pd.crosstab( index=df['row'], columns=df['col'], values=df['val0'], aggfunc='sum').fillna(0)
Pregunta 5
¿Puedo hacer más de una agregación a la vez?
Observe que para pivot_table
y cross_tab
necesitaba pasar la lista de llamadas. Por otro lado, groupby.agg
es capaz de tomar cadenas para un número limitado de funciones especiales. groupby.agg
también habría tomado los mismos callables que pasamos a los demás, pero a menudo es más eficiente aprovechar los nombres de función de cadena, ya que hay eficiencias para ser ganar.
-
pd.DataFrame.pivot_table
df.pivot_table( values='val0', index='row', columns='col', fill_value=0, aggfunc=[np.size, np.mean]) size mean col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4 row row0 1 2 0 1 1 0.77 0.605 0.000 0.860 0.65 row2 1 0 2 1 2 0.13 0.000 0.395 0.500 0.25 row3 0 1 0 2 0 0.00 0.310 0.000 0.545 0.00 row4 0 1 2 2 1 0.00 0.100 0.395 0.760 0.24
-
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].agg(['size', 'mean']).unstack(fill_value=0)
-
pd.crosstab
pd.crosstab( index=df['row'], columns=df['col'], values=df['val0'], aggfunc=[np.size, np.mean]).fillna(0, downcast='infer')
Pregunta 6
¿Puedo agregar sobre múltiples columnas de valor?
-
pd.DataFrame.pivot_table
pasamosvalues=['val0', 'val1']
pero podríamos haber dejado eso completamente{[92]]}df.pivot_table( values=['val0', 'val1'], index='row', columns='col', fill_value=0, aggfunc='mean') val0 val1 col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4 row row0 0.77 0.605 0.000 0.860 0.65 0.01 0.745 0.00 0.010 0.02 row2 0.13 0.000 0.395 0.500 0.25 0.45 0.000 0.34 0.440 0.79 row3 0.00 0.310 0.000 0.545 0.00 0.00 0.230 0.00 0.075 0.00 row4 0.00 0.100 0.395 0.760 0.24 0.00 0.070 0.42 0.300 0.46
-
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0', 'val1'].mean().unstack(fill_value=0)
Pregunta 7
Puede subdividirse por múltiples las columnas?
-
pd.DataFrame.pivot_table
df.pivot_table( values='val0', index='row', columns=['item', 'col'], fill_value=0, aggfunc='mean') item item0 item1 item2 col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4 row row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.605 0.86 0.65 row2 0.35 0.00 0.37 0.00 0.00 0.44 0.00 0.00 0.13 0.000 0.50 0.13 row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.000 0.28 0.00 row4 0.15 0.64 0.00 0.00 0.10 0.64 0.88 0.24 0.00 0.000 0.00 0.00
-
pd.DataFrame.groupby
df.groupby( ['row', 'item', 'col'] )['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)
Pregunta 8
¿Se puede subdividir por múltiples columnas?
-
pd.DataFrame.pivot_table
df.pivot_table( values='val0', index=['key', 'row'], columns=['item', 'col'], fill_value=0, aggfunc='mean') item item0 item1 item2 col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4 key row key0 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.86 0.00 row2 0.00 0.00 0.37 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.50 0.00 row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.00 0.00 0.00 row4 0.15 0.64 0.00 0.00 0.00 0.00 0.00 0.24 0.00 0.00 0.00 0.00 key1 row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.81 0.00 0.65 row2 0.35 0.00 0.00 0.00 0.00 0.44 0.00 0.00 0.00 0.00 0.00 0.13 row3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.28 0.00 row4 0.00 0.00 0.00 0.00 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 key2 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.40 0.00 0.00 row2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.13 0.00 0.00 0.00 row4 0.00 0.00 0.00 0.00 0.00 0.64 0.88 0.00 0.00 0.00 0.00 0.00
-
pd.DataFrame.groupby
df.groupby( ['key', 'row', 'item', 'col'] )['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)
-
pd.DataFrame.set_index
porque el conjunto de claves es único tanto para filas como para columnasdf.set_index( ['key', 'row', 'item', 'col'] )['val0'].unstack(['item', 'col']).fillna(0).sort_index(1)
Pregunta 9
¿Puedo agregar el ¿frecuencia en la que la columna y las filas ocurren juntas, también conocida como "tabulación cruzada"?
-
pd.DataFrame.pivot_table
df.pivot_table(index='row', columns='col', fill_value=0, aggfunc='size') col col0 col1 col2 col3 col4 row row0 1 2 0 1 1 row2 1 0 2 1 2 row3 0 1 0 2 0 row4 0 1 2 2 1
-
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].size().unstack(fill_value=0)
-
pd.cross_tab
pd.crosstab(df['row'], df['col'])
-
pd.factorize
+np.bincount
# get integer factorization `i` and unique values `r` # for column `'row'` i, r = pd.factorize(df['row'].values) # get integer factorization `j` and unique values `c` # for column `'col'` j, c = pd.factorize(df['col'].values) # `n` will be the number of rows # `m` will be the number of columns n, m = r.size, c.size # `i * m + j` is a clever way of counting the # factorization bins assuming a flat array of length # `n * m`. Which is why we subsequently reshape as `(n, m)` b = np.bincount(i * m + j, minlength=n * m).reshape(n, m) # BTW, whenever I read this, I think 'Bean, Rice, and Cheese' pd.DataFrame(b, r, c) col3 col2 col0 col1 col4 row3 2 0 0 1 0 row2 1 2 1 0 2 row0 1 0 1 2 1 row4 2 2 0 1 1
-
pd.get_dummies
pd.get_dummies(df['row']).T.dot(pd.get_dummies(df['col'])) col0 col1 col2 col3 col4 row0 1 2 0 1 1 row2 1 0 2 1 2 row3 0 1 0 2 0 row4 0 1 2 2 1
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-14 17:13:35