Convertir Python dict en un marco de datos


299

Tengo un diccionario de Python como el siguiente:

{u'2012-06-08': 388,
 u'2012-06-09': 388,
 u'2012-06-10': 388,
 u'2012-06-11': 389,
 u'2012-06-12': 389,
 u'2012-06-13': 389,
 u'2012-06-14': 389,
 u'2012-06-15': 389,
 u'2012-06-16': 389,
 u'2012-06-17': 389,
 u'2012-06-18': 390,
 u'2012-06-19': 390,
 u'2012-06-20': 390,
 u'2012-06-21': 390,
 u'2012-06-22': 390,
 u'2012-06-23': 390,
 u'2012-06-24': 390,
 u'2012-06-25': 391,
 u'2012-06-26': 391,
 u'2012-06-27': 391,
 u'2012-06-28': 391,
 u'2012-06-29': 391,
 u'2012-06-30': 391,
 u'2012-07-01': 391,
 u'2012-07-02': 392,
 u'2012-07-03': 392,
 u'2012-07-04': 392,
 u'2012-07-05': 392,
 u'2012-07-06': 392}

Las claves son fechas Unicode y los valores son enteros. Me gustaría convertir esto en un marco de datos de pandas al tener las fechas y sus valores correspondientes como dos columnas separadas. Ejemplo: col1: Fechas col2: DateValue (las fechas siguen siendo Unicode y los valores de fecha siguen siendo enteros)

     Date         DateValue
0    2012-07-01    391
1    2012-07-02    392
2    2012-07-03    392
.    2012-07-04    392
.    ...           ...
.    ...           ...

Cualquier ayuda en esta dirección sería muy apreciada. No puedo encontrar recursos en los documentos de pandas para ayudarme con esto.

Sé que una solución podría ser convertir cada par clave-valor en este dict, en un dict para que toda la estructura se convierta en un dict de dicts, y luego podamos agregar cada fila individualmente al marco de datos. Pero quiero saber si hay una manera más fácil y más directa de hacerlo.

Hasta ahora he intentado convertir el dict en un objeto en serie, pero esto no parece mantener la relación entre las columnas:

s  = Series(my_dict,index=my_dict.keys())

Intenté convertir el dict en un objeto en serie con las fechas como índice pero eso no coincidió con los valores correspondientes por alguna razón.
anonuser0428

El código ha sido publicado. Quiero preguntar si hay una manera de crear un marco de datos sin crear un dictado de dictados y luego agregar cada fila por separado.
anonuser0428

1
¿Qué es una "fecha Unicode"? ¿Te refieres a una fecha ISO 8601 ?
Peter Mortensen

Respuestas:


461

El error aquí, es desde llamar al constructor DataFrame con valores escalares (donde espera que los valores sean una lista / dict / ... es decir, que tengan varias columnas):

pd.DataFrame(d)
ValueError: If using all scalar values, you must must pass an index

Puede tomar los elementos del diccionario (es decir, los pares clave-valor):

In [11]: pd.DataFrame(d.items())  # or list(d.items()) in python 3
Out[11]:
             0    1
0   2012-07-02  392
1   2012-07-06  392
2   2012-06-29  391
3   2012-06-28  391
...

In [12]: pd.DataFrame(d.items(), columns=['Date', 'DateValue'])
Out[12]:
          Date  DateValue
0   2012-07-02        392
1   2012-07-06        392
2   2012-06-29        391

Pero creo que tiene más sentido pasar el constructor de la serie:

In [21]: s = pd.Series(d, name='DateValue')
Out[21]:
2012-06-08    388
2012-06-09    388
2012-06-10    388

In [22]: s.index.name = 'Date'

In [23]: s.reset_index()
Out[23]:
          Date  DateValue
0   2012-06-08        388
1   2012-06-09        388
2   2012-06-10        388

44
@ user1009091 Me di cuenta de lo que significa el error ahora, básicamente dice "Lo que estoy viendo es una serie, así que use el constructor de la serie".
Andy Hayden

1
Gracias, muy útil. ¿Podría explicar cuál es la diferencia entre usar este método y usar DataFrame.from_dict ()? Su método (que utilicé) devuelve type = pandas.core.frame.DataFrame, mientras que el otro devuelve type = class 'pandas.core.frame.DataFrame'. ¿Alguna posibilidad de que puedas explicar la diferencia y cuándo cada método es apropiado? Gracias de antemano :)
Optimesh

Ambos son similares, from_dicttienen un kwarg orientado, por lo que podría usarlo si quisiera evitar la transposición. Hay pocas opciones con from_dict, debajo del capó no es realmente diferente de usar el constructor DataFrame.
Andy Hayden

54
Estoy viendo pandas.core.common.PandasError: DataFrame constructor not properly called!desde el primer ejemplo
allthesignals

18
@allthesignals agregar lista () alrededor de d.items funciona: pd.DataFrame (list (d.items ()), columnas = ['Fecha', 'Valor de fecha'])
sigurdb

142

Al convertir un diccionario en un marco de datos de pandas donde desea que las claves sean las columnas de dicho marco de datos y los valores sean los valores de fila, puede simplemente poner corchetes alrededor del diccionario de esta manera:

>>> dict_ = {'key 1': 'value 1', 'key 2': 'value 2', 'key 3': 'value 3'}
>>> pd.DataFrame([dict_])

    key 1     key 2     key 3
0   value 1   value 2   value 3

¡Me ha ahorrado algunos dolores de cabeza, así que espero que ayude a alguien!

EDITAR: en los documentos de pandas, una opción para el dataparámetro en el constructor DataFrame es una lista de diccionarios. Aquí estamos pasando una lista con un diccionario en ella.


66
Sí, también hice esto pero agregué .T para transponer.
Anton vBR

1
Funciona bien, pero no sé por qué tenemos que hacerlo así.
hui chen

¿Y si quiero una columna de éstos para ser utilizado como índice
om tripathi

102

Como se explica en otra respuesta, usar pandas.DataFrame()directamente aquí no actuará como usted piensa.

Lo que puedes hacer es usar pandas.DataFrame.from_dictcon orient='index':

In[7]: pandas.DataFrame.from_dict({u'2012-06-08': 388,
 u'2012-06-09': 388,
 u'2012-06-10': 388,
 u'2012-06-11': 389,
 u'2012-06-12': 389,
 .....
 u'2012-07-05': 392,
 u'2012-07-06': 392}, orient='index', columns=['foo'])
Out[7]: 
            foo
2012-06-08  388
2012-06-09  388
2012-06-10  388
2012-06-11  389
2012-06-12  389
........
2012-07-05  392
2012-07-06  392

1
¿podemos encadenar esto con algún renamemétodo para establecer también los nombres del índice y las columnas de una vez?
Ciprian Tomoiagă

44
buen punto. Un ejemplo sería: ...., orient = 'index'). Rename (columnas = {0: 'foobar'})
ntg

1
También puede especificar pandas.DataFrame.from_dict (..., orient = 'index', columnas = ['foo', 'bar']), esto es de la fuente mencionada anteriormente .
spen.smith

buen punto, esto es cierto para los pandas .22 que fue después de la respuesta original ...
Actualicé

69

Pase los elementos del diccionario al constructor DataFrame y proporcione los nombres de las columnas. Después de eso, analice la Datecolumna para obtener Timestampvalores.

Tenga en cuenta la diferencia entre python 2.xy 3.x:

En python 2.x:

df = pd.DataFrame(data.items(), columns=['Date', 'DateValue'])
df['Date'] = pd.to_datetime(df['Date'])

En Python 3.x: (requiere una 'lista' adicional)

df = pd.DataFrame(list(data.items()), columns=['Date', 'DateValue'])
df['Date'] = pd.to_datetime(df['Date'])

3
Esto me da:PandasError: DataFrame constructor not properly called!
Chris Nielsen

18
@ChrisNielsen Probablemente estés usando python3. Deberías probar:df = pd.DataFrame(list(data.items()), columns=['Date', 'DateValue'])
Viktor Kerkez

Esta es la mejor respuesta porque muestra lo que debe hacerse en Python 3.
ifly6


10

Los pandas tienen una función incorporada para la conversión de dict a marco de datos.

pd.DataFrame.from_dict (dictionaryObject, orient = 'index')

Para sus datos, puede convertirlos de la siguiente manera:

import pandas as pd
your_dict={u'2012-06-08': 388,
 u'2012-06-09': 388,
 u'2012-06-10': 388,
 u'2012-06-11': 389,
 u'2012-06-12': 389,
 u'2012-06-13': 389,
 u'2012-06-14': 389,
 u'2012-06-15': 389,
 u'2012-06-16': 389,
 u'2012-06-17': 389,
 u'2012-06-18': 390,
 u'2012-06-19': 390,
 u'2012-06-20': 390,
 u'2012-06-21': 390,
 u'2012-06-22': 390,
 u'2012-06-23': 390,
 u'2012-06-24': 390,
 u'2012-06-25': 391,
 u'2012-06-26': 391,
 u'2012-06-27': 391,
 u'2012-06-28': 391,
 u'2012-06-29': 391,
 u'2012-06-30': 391,
 u'2012-07-01': 391,
 u'2012-07-02': 392,
 u'2012-07-03': 392,
 u'2012-07-04': 392,
 u'2012-07-05': 392,
 u'2012-07-06': 392}

your_df_from_dict=pd.DataFrame.from_dict(your_dict,orient='index')
print(your_df_from_dict)

2
Esa es una solución realmente mala, ya que guarda las claves del diccionario como índice.
Un economista

6
pd.DataFrame({'date' : dict_dates.keys() , 'date_value' : dict_dates.values() })

5

También puede pasar las claves y los valores del diccionario al nuevo marco de datos, así:

import pandas as pd

myDict = {<the_dict_from_your_example>]
df = pd.DataFrame()
df['Date'] = myDict.keys()
df['DateValue'] = myDict.values()

5

En mi caso, quería que las claves y los valores de un dict fueran columnas y valores de DataFrame. Entonces, lo único que funcionó para mí fue:

data = {'adjust_power': 'y', 'af_policy_r_submix_prio_adjust': '[null]', 'af_rf_info': '[null]', 'bat_ac': '3500', 'bat_capacity': '75'} 

columns = list(data.keys())
values = list(data.values())
arr_len = len(values)

pd.DataFrame(np.array(values, dtype=object).reshape(1, arr_len), columns=columns)

5

Esto es lo que funcionó para mí, ya que quería tener una columna de índice separada

df = pd.DataFrame.from_dict(some_dict, orient="index").reset_index()
df.columns = ['A', 'B']

3

Acepta un dict como argumento y devuelve un marco de datos con las claves del dict como índice y los valores como una columna.

def dict_to_df(d):
    df=pd.DataFrame(d.items())
    df.set_index(0, inplace=True)
    return df

tome un dict, devuelve un marco de datos
primero

3

Así es como funcionó para mí:

df= pd.DataFrame([d.keys(), d.values()]).T
df.columns= ['keys', 'values']  # call them whatever you like

espero que esto ayude


1
d = {'Date': list(yourDict.keys()),'Date_Values': list(yourDict.values())}
df = pandas.DataFrame(data=d)

Si no encapsula yourDict.keys()dentro de list(), entonces terminará con todas sus claves y valores colocados en cada fila de cada columna. Me gusta esto:

Date \ 0 (2012-06-08, 2012-06-09, 2012-06-10, 2012-06-1...
1 (2012-06-08, 2012-06-09, 2012-06-10, 2012-06-1...
2 (2012-06-08, 2012-06-09, 2012-06-10, 2012-06-1...
3 (2012-06-08, 2012-06-09, 2012-06-10, 2012-06-1...
4 (2012-06-08, 2012-06-09, 2012-06-10, 2012-06-1...

Pero al agregar list(), el resultado se ve así:

Date Date_Values 0 2012-06-08 388 1 2012-06-09 388 2 2012-06-10 388 3 2012-06-11 389 4 2012-06-12 389 ...


0

Me he encontrado con esto varias veces y tengo un diccionario de ejemplo que creé a partir de una función get_max_Path(), y me devuelve el diccionario de muestra:

{2: 0.3097502930247044, 3: 0.4413177909384636, 4: 0.5197224051562838, 5: 0.5717654946470984, 6: 0.6063959031223476, 7: 0.6365209824708223, 8: 0.655918861281035, 9: 0.680844386645206}

Para convertir esto en un marco de datos, ejecuté lo siguiente:

df = pd.DataFrame.from_dict(get_max_path(2), orient = 'index').reset_index()

Devuelve un marco de datos simple de dos columnas con un índice separado:

index 0 0 2 0.309750 1 3 0.441318

Simplemente cambie el nombre de las columnas usando f.rename(columns={'index': 'Column1', 0: 'Column2'}, inplace=True)


0

Creo que puede hacer algunos cambios en su formato de datos cuando crea un diccionario, luego puede convertirlo fácilmente a DataFrame:

entrada:

a={'Dates':['2012-06-08','2012-06-10'],'Date_value':[388,389]}

salida:

{'Date_value': [388, 389], 'Dates': ['2012-06-08', '2012-06-10']}

entrada:

aframe=DataFrame(a)

salida: será su DataFrame

Solo necesita usar algo de edición de texto en algún lugar como Sublime o tal vez Excel.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.