Tengo una lista de diccionarios como este:
[{'points': 50, 'time': '5:00', 'year': 2010},
{'points': 25, 'time': '6:00', 'month': "february"},
{'points':90, 'time': '9:00', 'month': 'january'},
{'points_h1':20, 'month': 'june'}]
Y quiero convertir esto en un panda DataFrame
Me gusta esto:
month points points_h1 time year
0 NaN 50 NaN 5:00 2010
1 february 25 NaN 6:00 NaN
2 january 90 NaN 9:00 NaN
3 june NaN 20 NaN NaN
Nota: El orden de las columnas no importa.
¿Cómo puedo convertir la lista de diccionarios en un DataFrame de pandas como se muestra arriba?
¿Cómo convierto una lista de diccionarios en un DataFrame de pandas?
Las otras respuestas son correctas, pero no se ha explicado mucho en términos de ventajas y limitaciones de estos métodos. El objetivo de esta publicación será mostrar ejemplos de estos métodos en diferentes situaciones, discutir cuándo usarlos (y cuándo no usarlos) y sugerir alternativas.
Según la estructura y el formato de sus datos, hay situaciones en las que funcionan los tres métodos, o algunos funcionan mejor que otros, o algunos no funcionan en absoluto.
Considere un ejemplo muy artificial.
np.random.seed(0)
data = pd.DataFrame(
np.random.choice(10, (3, 4)), columns=list('ABCD')).to_dict('r')
print(data)
[{'A': 5, 'B': 0, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'C': 3, 'D': 5},
{'A': 2, 'B': 4, 'C': 7, 'D': 6}]
Esta lista consta de “registros” con todas las claves presentes. Este es el caso más simple que podría encontrar.
# The following methods all produce the same output.
pd.DataFrame(data)
pd.DataFrame.from_dict(data)
pd.DataFrame.from_records(data)
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
Palabra en Orientaciones del Diccionario: orient="index"
/'columns'
Antes de continuar, es importante hacer la distinción entre los diferentes tipos de orientaciones del diccionario y el soporte con pandas. Hay dos tipos principales: “columnas” e “índice”.
orient="columns"
Los diccionarios con la orientación de “columnas” tendrán sus claves correspondientes a las columnas en el DataFrame equivalente.
Por ejemplo, data
arriba está en el oriente de “columnas”.
data_c = [
{'A': 5, 'B': 0, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'C': 3, 'D': 5},
{'A': 2, 'B': 4, 'C': 7, 'D': 6}]
pd.DataFrame.from_dict(data_c, orient="columns")
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
Nota: Si está utilizando pd.DataFrame.from_records
se supone que la orientación es “columnas” (no puede especificar lo contrario), y los diccionarios se cargarán en consecuencia.
orient="index"
Con esta orientación, se supone que las claves corresponden a valores de índice. Este tipo de datos es más adecuado para pd.DataFrame.from_dict
.
data_i ={
0: {'A': 5, 'B': 0, 'C': 3, 'D': 3},
1: {'A': 7, 'B': 9, 'C': 3, 'D': 5},
2: {'A': 2, 'B': 4, 'C': 7, 'D': 6}}
pd.DataFrame.from_dict(data_i, orient="index")
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
Este caso no se considera en el OP, pero aún así es útil saberlo.
Configuración del índice personalizado
Si necesita un índice personalizado en el DataFrame resultante, puede configurarlo usando el index=...
argumento.
pd.DataFrame(data, index=['a', 'b', 'c'])
# pd.DataFrame.from_records(data, index=['a', 'b', 'c'])
A B C D
a 5 0 3 3
b 7 9 3 5
c 2 4 7 6
Esto no está respaldado por pd.DataFrame.from_dict
.
Manejo de claves/columnas faltantes
Todos los métodos funcionan de manera inmediata cuando se manejan diccionarios a los que les faltan claves o valores de columna. Por ejemplo,
data2 = [
{'A': 5, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'F': 5},
{'B': 4, 'C': 7, 'E': 6}]
# The methods below all produce the same output.
pd.DataFrame(data2)
pd.DataFrame.from_dict(data2)
pd.DataFrame.from_records(data2)
A B C D E F
0 5.0 NaN 3.0 3.0 NaN NaN
1 7.0 9.0 NaN NaN NaN 5.0
2 NaN 4.0 7.0 NaN 6.0 NaN
Subconjunto de lectura de columnas
“¿Qué pasa si no quiero leer en cada columna”? Puede especificar esto fácilmente usando el columns=...
parámetro.
Por ejemplo, del diccionario de ejemplos de data2
arriba, si desea leer solo las columnas “A”, “D” y “F”, puede hacerlo pasando una lista:
pd.DataFrame(data2, columns=['A', 'D', 'F'])
# pd.DataFrame.from_records(data2, columns=['A', 'D', 'F'])
A D F
0 5.0 3.0 NaN
1 7.0 NaN 5.0
2 NaN NaN NaN
Esto no está respaldado por pd.DataFrame.from_dict
con las “columnas” de orientación predeterminadas.
pd.DataFrame.from_dict(data2, orient="columns", columns=['A', 'B'])
ValueError: cannot use columns parameter with orient="columns"
Leer subconjunto de filas
No compatible con ninguno de estos métodos directamente. Tendrá que iterar sobre sus datos y realizar una eliminación inversa en el lugar mientras itera. Por ejemplo, para extraer solo el 0el y 2Dakota del Norte filas de data2
arriba, puedes usar:
rows_to_select = {0, 2}
for i in reversed(range(len(data2))):
if i not in rows_to_select:
del data2[i]
pd.DataFrame(data2)
# pd.DataFrame.from_dict(data2)
# pd.DataFrame.from_records(data2)
A B C D E
0 5.0 NaN 3 3.0 NaN
1 NaN 4.0 7 NaN 6.0
La panacea: json_normalize
para datos anidados
Una alternativa fuerte y robusta a los métodos descritos anteriormente es el json_normalize
función que trabaja con listas de diccionarios (registros), y además también puede manejar diccionarios anidados.
pd.json_normalize(data)
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
pd.json_normalize(data2)
A B C D E
0 5.0 NaN 3 3.0 NaN
1 NaN 4.0 7 NaN 6.0
Una vez más, tenga en cuenta que los datos pasados a json_normalize
debe estar en formato de lista de diccionarios (registros).
Como se mencionó, json_normalize
también puede manejar diccionarios anidados. Aquí hay un ejemplo tomado de la documentación.
data_nested = [
{'counties': [{'name': 'Dade', 'population': 12345},
{'name': 'Broward', 'population': 40000},
{'name': 'Palm Beach', 'population': 60000}],
'info': {'governor': 'Rick Scott'},
'shortname': 'FL',
'state': 'Florida'},
{'counties': [{'name': 'Summit', 'population': 1234},
{'name': 'Cuyahoga', 'population': 1337}],
'info': {'governor': 'John Kasich'},
'shortname': 'OH',
'state': 'Ohio'}
]
pd.json_normalize(data_nested,
record_path="counties",
meta=['state', 'shortname', ['info', 'governor']])
name population state shortname info.governor
0 Dade 12345 Florida FL Rick Scott
1 Broward 40000 Florida FL Rick Scott
2 Palm Beach 60000 Florida FL Rick Scott
3 Summit 1234 Ohio OH John Kasich
4 Cuyahoga 1337 Ohio OH John Kasich
Para obtener más información sobre el meta
y record_path
argumentos, echa un vistazo a la documentación.
resumiendo
Aquí hay una tabla de todos los métodos discutidos anteriormente, junto con las características/funcionalidad compatibles.

* Utilizar orient="columns"
y luego transponer para obtener el mismo efecto que orient="index"
.