Construya pandas DataFrame a partir de la lista de tuplas de (fila, columna, valores)

81

Tengo una lista de tuplas como

data = [
('r1', 'c1', avg11, stdev11),
('r1', 'c2', avg12, stdev12),
('r2', 'c1', avg21, stdev21),
('r2', 'c2', avg22, stdev22)
]

y me gustaría ponerlos en un DataFrame de pandas con filas nombradas por la primera columna y columnas nombradas por la segunda columna. Parece que la forma de cuidar los nombres de las filas es algo así, pandas.DataFrame([x[1:] for x in data], index = [x[0] for x in data])pero ¿cómo cuido las columnas para obtener una matriz de 2x2 (la salida del conjunto anterior es 3x4)? ¿Existe una forma más inteligente de cuidar las etiquetas de fila también, en lugar de omitirlas explícitamente?

EDITAR Parece que necesitaré 2 DataFrames, uno para promedios y otro para desviaciones estándar, ¿es correcto? ¿O puedo almacenar una lista de valores en cada "celda"?

gt6989b
fuente
1
Duplicado definitivo de < stackoverflow.com/questions/11415701/… >
ely
2
@EMS para nada. Vi esa pregunta, no necesitaba el pivote 2D.
gt6989b
No estoy de acuerdo, creo que simplemente no está familiarizado con la forma correcta de apilar datos en un DataFrame. En general, usted desea utilizar la información en ambos sus índices de la columna 1 y la columna 2 como, por lo que puede buscar rápidamente los datos por cualquiera. Las cosas en la columna 2 no pertenecen como nombres de columna, pero incluso si lo hacen, esta es una pregunta completamente separada del título de su publicación. Supongo que editar el título podría ayudar (aunque todavía creo que no es una pregunta significativamente diferente).
ely
1
@ely, gt6989b que el nuevo título de este "... lista de tuplas de (fila, columna, valores) de" dejar en claro por qué esto es no es un duplicado de "... de tuplas"
SMCI

Respuestas:

65

Puede girar su DataFrame después de crear:

>>> df = pd.DataFrame(data)
>>> df.pivot(index=0, columns=1, values=2)
# avg DataFrame
1      c1     c2
0               
r1  avg11  avg12
r2  avg21  avg22
>>> df.pivot(index=0, columns=1, values=3)
# stdev DataFrame
1        c1       c2
0                   
r1  stdev11  stdev12
r2  stdev21  stdev22
Roman Pekar
fuente
3
La fila con el índice 0y la columna con el nombre 1no son muy bonitas ...
drevicko
49

Sugiero que es mejor dejar sus datos apilados como están:

df = pandas.DataFrame(data, columns=['R_Number', 'C_Number', 'Avg', 'Std'])

# Possibly also this if these can always be the indexes:
# df = df.set_index(['R_Number', 'C_Number'])

Entonces es un poco más intuitivo decir

df.set_index(['R_Number', 'C_Number']).Avg.unstack(level=1)

De esta manera, está implícito que está buscando remodelar los promedios o las desviaciones estándar. Mientras que, solo usar pivot, se basa puramente en la convención de columna en cuanto a qué entidad semántica es la que está remodelando.

ely
fuente
1
+1, claridad útil. Estoy explícitamente interesado en una tabla 2D, para permitirme buscar valores, indexados por listas de filas y columnas, así como acceder a cada una de las dimensiones por separado. ¿Puedes hacer eso con datos apilados?
gt6989b
2
Sí. Mucho mejor con datos apilados. Piense en una tabla de base de datos relacional, como en SQL. No vas a soplar una columna completa en un montón de columnas repetidas, ¿verdad? Eso solo debería suceder en casos especiales (creo que es el patrón de alto a ancho). Normalmente, trata varias columnas como índices y realiza selecciones vinculando parcialmente una de las columnas de índice o vinculándolas todas para obtener un registro específico.
ely
2
Entonces, en su caso, después de configurar el índice [R_Number, C_Number], puede hacerlo df.ix[('r1','c2')], por ejemplo. O puede dejar los tanto como columnas regulares y utilizar la indexación lógica:df[(df.R_Number == 'r1') & (df.C_Number == 'c2')]
Ely
2
Generalmente, el caso de uso principal para hacer lo que está tratando de hacer pivotes cuando está formateando una tabla para que se imprima bien en la pantalla, o se exporte bien a HTML, LaTeX o .csv, o algo así. Como formatear una tabla que se incluirá en una presentación o envío de un artículo. De lo contrario, en lo que respecta a manipular datos de manera eficiente, desea que las cosas sean índices múltiples cuando pueda (como claves para una tabla de base de datos) o al menos como columnas repetidas para que pueda indexar y unir de manera eficiente, etc. Pero no lo hace quieren hacerlos estallar en sus propias columnas.
ely
35

Esto es lo que esperaba ver cuando llegué a esta pregunta:

#!/usr/bin/env python

import pandas as pd


df = pd.DataFrame([(1, 2, 3, 4),
                   (5, 6, 7, 8),
                   (9, 0, 1, 2),
                   (3, 4, 5, 6)],
                  columns=list('abcd'),
                  index=['India', 'France', 'England', 'Germany'])
print(df)

da

         a  b  c  d
India    1  2  3  4
France   5  6  7  8
England  9  0  1  2
Germany  3  4  5  6
Martín Thoma
fuente
Has leído mal la pregunta. Los datos proporcionados originalmente en la pregunta ya tienen etiquetas de fila y columna para cada registro en cuestión.
gt6989b
11
@ gt6989b No, no lo hice. No intenté responder a la pregunta original, sino a la pregunta que la gente (podría) tener cuando llegue a esta página.
Martin Thoma
8
@MartinThoma Gracias, de hecho esto es lo que estoy buscando en esta página.
ssword