marco de datos de python pandas al diccionario


111

Tengo un marco de datos de dos columnas y tengo la intención de convertirlo en un diccionario de Python: la primera columna será la clave y la segunda será el valor. Gracias de antemano.

Marco de datos:

    id    value
0    0     10.2
1    1      5.7
2    2      7.4



4
@perigee: ¿Puede aceptar una de las respuestas (si es útil) para marcar la pregunta como resuelta? Esto también ayudará a otros usuarios.
MERose

si tiene una identificación que coincide con el índice, debe establecerla como índice.
Faris

Respuestas:


152

Consulte los documentos para to_dict. Puedes usarlo así:

df.set_index('id').to_dict()

Y si solo tiene una columna, para evitar que el nombre de la columna también sea un nivel en el dict (en realidad, en este caso usa Series.to_dict()):

df.set_index('id')['value'].to_dict()

14
Tenga en cuenta que este comando perderá datos si hay valores redundantes en las columnas de ID: >>> ptest = p.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) >>> ptest.set_index('id')['value'].to_dict()
dalloliogm

9
Debo decir que no hay nada en ese enlace de documentos que me hubiera dado la respuesta a esta pregunta.
Ben Fulton

@bombayquant vea las respuestas de DSM y mías a continuación. Tenga en cuenta que esta es una discusión de 4 años.
dalloliogm

66
mydict = dict(zip(df.id, df.value))

1
Nota: en caso de que el índice sea la clave de diccionario deseada, haga: dict (zip (df.index, df.value))
aLbAc

47

Si desea una forma sencilla de conservar los duplicados, puede utilizar groupby:

>>> ptest = pd.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) 
>>> ptest
  id  value
0  a      1
1  a      2
2  b      3
>>> {k: g["value"].tolist() for k,g in ptest.groupby("id")}
{'a': [1, 2], 'b': [3]}

1
Solución agradable y elegante, pero en una tabla de 50k filas, es aproximadamente 6 veces más lenta que mi fea solución a continuación.
dalloliogm

@dalloliogm: ¿podría dar una tabla de ejemplo que suceda para? Si es seis veces más lento que un bucle de Python, es posible que haya un error de rendimiento en pandas.
DSM

23

Las respuestas de joris en este hilo y de punchagan en el hilo duplicado son muy elegantes, sin embargo no darán resultados correctos si la columna usada para las claves contiene algún valor duplicado.

Por ejemplo:

>>> ptest = p.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) 
>>> ptest
  id  value
0  a      1
1  a      2
2  b      3

# note that in both cases the association a->1 is lost:
>>> ptest.set_index('id')['value'].to_dict()
{'a': 2, 'b': 3}
>>> dict(zip(ptest.id, ptest.value))
{'a': 2, 'b': 3}

Si tiene entradas duplicadas y no quiere perderlas, puede usar este código feo pero funcional:

>>> mydict = {}
>>> for x in range(len(ptest)):
...     currentid = ptest.iloc[x,0]
...     currentvalue = ptest.iloc[x,1]
...     mydict.setdefault(currentid, [])
...     mydict[currentid].append(currentvalue)
>>> mydict
{'a': [1, 2], 'b': [3]}

2
Disculpe el formato debido a la falta de un bloque en los comentarios:mydict = defaultdict(list)\n for (key, val) in ptest[["id", "value"]].itertuples(index=False):\n mydict[key].append(val)
Midnighter

1
Aunque no es tan elegante como una sola línea, me gustó mucho más tu solución.
Peter Maguire

9

Solución más sencilla:

df.set_index('id').T.to_dict('records')

Ejemplo:

df= pd.DataFrame([['a',1],['a',2],['b',3]], columns=['id','value'])
df.set_index('id').T.to_dict('records')

Si tiene varios valores, como val1, val2, val3, etc. y los quiere como listas, utilice el siguiente código:

df.set_index('id').T.to_dict('list')

1
que recordssignifica aqui
mingchau

1
@mingchau recordsaquí significa ‘records’ : list like [{column -> value}, … , {column -> value}] Ver pandas.pydata.org/pandas-docs/stable/reference/api/…
AmuletxHeart

8

en algunas versiones, es posible que el código siguiente no funcione

mydict = dict(zip(df.id, df.value))

así que hazlo explícito

id_=df.id.values
value=df.value.values
mydict=dict(zip(id_,value))

Tenga en cuenta que usé id_ porque la palabra id es palabra reservada


7

Puede usar 'dict comprehension'

my_dict = {row[0]: row[1] for row in df.values}

Hacer un bucle con pandas no es el más eficiente en términos de uso de memoria. Ver: engineering.upside.com/…
tda

OP no pidió la respuesta más eficiente, así que creo que @Dongwan Kim proporcionó una buena solución alternativa.
Un economista

3

Otra solución (un poco más corta) para no perder entradas duplicadas:

>>> ptest = pd.DataFrame([['a',1],['a',2],['b',3]], columns=['id','value'])
>>> ptest
  id  value
0  a      1
1  a      2
2  b      3

>>> pdict = dict()
>>> for i in ptest['id'].unique().tolist():
...     ptest_slice = ptest[ptest['id'] == i]
...     pdict[i] = ptest_slice['value'].tolist()
...

>>> pdict
{'b': [3], 'a': [1, 2]}

1

Necesita una lista como valor de diccionario. Este código hará el truco.

from collections import defaultdict
mydict = defaultdict(list)
for k, v in zip(df.id.values,df.value.values):
    mydict[k].append(v)

1

Encontré esta pregunta mientras intentaba hacer un diccionario con tres columnas de un marco de datos de pandas. En mi caso, el marco de datos tiene columnas A, B y C (digamos que A y B son las coordenadas geográficas de longitud y latitud y C la región del país / estado / etc., que es más o menos el caso).

Quería un diccionario con cada par de valores A, B (clave del diccionario) que coincida con el valor de C (valor del diccionario) en la fila correspondiente ( se garantiza que cada par de valores A, B es único debido al filtrado anterior, pero es posible tener el mismo valor de C para diferentes pares de valores A, B en este contexto), así que lo hice:

mydict = dict(zip(zip(df['A'],df['B']), df['C']))

Usar pandas to_dict () también funciona:

mydict = df.set_index(['A','B']).to_dict(orient='dict')['C']

(ninguna de las columnas A o B se utilizó como índice antes de ejecutar la línea de creación del diccionario)

Ambos enfoques son rápidos (menos de un segundo en un marco de datos con 85.000 filas, una computadora portátil rápida de doble núcleo de 5 años de antigüedad).

Las razones por las que publico esto:

  1. para quienes necesitan este tipo de solución
  2. si alguien conoce una solución de ejecución más rápida (por ejemplo, para millones de filas), agradecería una respuesta.

0
def get_dict_from_pd(df, key_col, row_col):
    result = dict()
    for i in set(df[key_col].values):
        is_i = df[key_col] == i
        result[i] = list(df[is_i][row_col].values)
    return result

este es mi sloution, un bucle básico


0

Esta es mi solucion:

import pandas as pd
df = pd.read_excel('dic.xlsx')
df_T = df.set_index('id').T
dic = df_T.to_dict('records')
print(dic)
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.