Convierta un DataFrame de Pandas a un diccionario

168

Tengo un DataFrame con cuatro columnas. Quiero convertir este DataFrame en un diccionario de Python. Quiero que los elementos de la primera columna sean keysy los elementos de otras columnas en la misma fila values.

Marco de datos:

    ID   A   B   C
0   p    1   3   2
1   q    4   3   2
2   r    4   0   9  

La salida debería ser así:

Diccionario:

{'p': [1,3,2], 'q': [4,3,2], 'r': [4,0,9]}
Príncipe Bhatti
fuente
44
Dataframe.to_dict()?
Anzel
3
Dataframe.to_dict()hará A,B,Clas llaves en lugar dep,q,r
Prince Bhatti
@jezrael ¿cómo obtener el siguiente resultado? {2: {'p': [1,3]}, 2: {'q': [4,3]}, 9: {'r': [4,0]}} para el mismo conjunto de datos?
panda
@jezrael equivalentes de columna de la pregunta anterior {'c': {'ID': 'A', 'B'}}
panda

Respuestas:

338

El to_dict()método establece los nombres de las columnas como claves de diccionario, por lo que deberá reformar ligeramente su DataFrame. Establecer la columna 'ID' como índice y luego transponer el DataFrame es una forma de lograr esto.

to_dict()También acepta un argumento 'orientar' que necesitará para generar una lista de valores para cada columna. De lo contrario, {index: value}se devolverá un diccionario del formulario para cada columna.

Estos pasos se pueden realizar con la siguiente línea:

>>> df.set_index('ID').T.to_dict('list')
{'p': [1, 3, 2], 'q': [4, 3, 2], 'r': [4, 0, 9]}

En caso de que se necesite un formato de diccionario diferente, aquí hay ejemplos de los posibles argumentos orientales. Considere el siguiente DataFrame simple:

>>> df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})
>>> df
        a      b
0     red  0.500
1  yellow  0.250
2    blue  0.125

Entonces las opciones son las siguientes.

dict - el valor predeterminado: los nombres de columna son claves, los valores son diccionarios de índice: pares de datos

>>> df.to_dict('dict')
{'a': {0: 'red', 1: 'yellow', 2: 'blue'}, 
 'b': {0: 0.5, 1: 0.25, 2: 0.125}}

lista : las claves son nombres de columna, los valores son listas de datos de columna

>>> df.to_dict('list')
{'a': ['red', 'yellow', 'blue'], 
 'b': [0.5, 0.25, 0.125]}

series - como 'lista', pero los valores son Series

>>> df.to_dict('series')
{'a': 0       red
      1    yellow
      2      blue
      Name: a, dtype: object, 

 'b': 0    0.500
      1    0.250
      2    0.125
      Name: b, dtype: float64}

dividido : divide columnas / datos / índice como claves con valores que son nombres de columnas, valores de datos por fila y etiquetas de índice respectivamente

>>> df.to_dict('split')
{'columns': ['a', 'b'],
 'data': [['red', 0.5], ['yellow', 0.25], ['blue', 0.125]],
 'index': [0, 1, 2]}

registros : cada fila se convierte en un diccionario donde la clave es el nombre de la columna y el valor son los datos en la celda

>>> df.to_dict('records')
[{'a': 'red', 'b': 0.5}, 
 {'a': 'yellow', 'b': 0.25}, 
 {'a': 'blue', 'b': 0.125}]

índice - como 'registros', pero un diccionario de diccionarios con claves como etiquetas de índice (en lugar de una lista)

>>> df.to_dict('index')
{0: {'a': 'red', 'b': 0.5},
 1: {'a': 'yellow', 'b': 0.25},
 2: {'a': 'blue', 'b': 0.125}}
Alex Riley
fuente
14
este será un trazador de líneas:df.set_index('ID').T.to_dict('list')
Anzel
1
Para un registro en Data Frame. df.T.to_dict () [0]
kamran kausar
23

Tratar de usar Zip

df = pd.read_csv("file")
d= dict([(i,[a,b,c ]) for i, a,b,c in zip(df.ID, df.A,df.B,df.C)])
print d

Salida:

{'p': [1, 3, 2], 'q': [4, 3, 2], 'r': [4, 0, 9]}

fuente
21

Sigue estos pasos:

Suponga que su marco de datos es el siguiente:

>>> df
   A  B  C ID
0  1  3  2  p
1  4  3  2  q
2  4  0  9  r

1. Use set_indexpara establecer IDcolumnas como el índice del marco de datos.

    df.set_index("ID", drop=True, inplace=True)

2. Use el orient=indexparámetro para tener el índice como claves de diccionario.

    dictionary = df.to_dict(orient="index")

Los resultados serán los siguientes:

    >>> dictionary
    {'q': {'A': 4, 'B': 3, 'D': 2}, 'p': {'A': 1, 'B': 3, 'D': 2}, 'r': {'A': 4, 'B': 0, 'D': 9}}

3. Si necesita tener cada muestra como una lista, ejecute el siguiente código. Determinar el orden de las columnas.

column_order= ["A", "B", "C"] #  Determine your preferred order of columns
d = {} #  Initialize the new dictionary as an empty dictionary
for k in dictionary:
    d[k] = [dictionary[k][column_name] for column_name in column_order]
Farhad Maleki
fuente
2
Para el último bit parece que sería más simple usar una comprensión dict para reemplazar la comprensión for loop + list (3 líneas -> 1). De cualquier manera, aunque es bueno tener opciones, la respuesta principal es mucho más corta.
fantabolous
Esto es útil porque explica claramente cómo usar una columna o encabezado específico como índice.
Tropicalrambler
10

Si no le importa que los valores del diccionario sean tuplas, puede usar itertuples:

>>> {x[0]: x[1:] for x in df.itertuples(index=False)}
{'p': (1, 3, 2), 'q': (4, 3, 2), 'r': (4, 0, 9)}
Kamil Sindi
fuente
7

debería un diccionario como:

{'red': '0.500', 'yellow': '0.250, 'blue': '0.125'}

ser requerido fuera de un marco de datos como:

        a      b
0     red  0.500
1  yellow  0.250
2    blue  0.125

la forma más sencilla sería hacer:

dict(df.values.tolist())

fragmento de trabajo a continuación:

import pandas as pd
df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})
dict(df.values.tolist())

ingrese la descripción de la imagen aquí

Muhammad Moiz Ahmed
fuente
2

Para mi uso (nombres de nodo con posiciones xy) encontré la respuesta de @ user4179775 a la más útil / intuitiva:

import pandas as pd

df = pd.read_csv('glycolysis_nodes_xy.tsv', sep='\t')

df.head()
    nodes    x    y
0  c00033  146  958
1  c00031  601  195
...

xy_dict_list=dict([(i,[a,b]) for i, a,b in zip(df.nodes, df.x,df.y)])

xy_dict_list
{'c00022': [483, 868],
 'c00024': [146, 868],
 ... }

xy_dict_tuples=dict([(i,(a,b)) for i, a,b in zip(df.nodes, df.x,df.y)])

xy_dict_tuples
{'c00022': (483, 868),
 'c00024': (146, 868),
 ... }

Apéndice

Más tarde volví a este tema, para otro trabajo, pero relacionado. Aquí hay un enfoque que refleja más de cerca la respuesta [excelente] aceptada.

node_df = pd.read_csv('node_prop-glycolysis_tca-from_pg.tsv', sep='\t')

node_df.head()
   node  kegg_id kegg_cid            name  wt  vis
0  22    22       c00022   pyruvate        1   1
1  24    24       c00024   acetyl-CoA      1   1
...

Convierta el marco de datos de Pandas en una [lista], {dict}, {dict of {dict}}, ...

Por respuesta aceptada:

node_df.set_index('kegg_cid').T.to_dict('list')

{'c00022': [22, 22, 'pyruvate', 1, 1],
 'c00024': [24, 24, 'acetyl-CoA', 1, 1],
 ... }

node_df.set_index('kegg_cid').T.to_dict('dict')

{'c00022': {'kegg_id': 22, 'name': 'pyruvate', 'node': 22, 'vis': 1, 'wt': 1},
 'c00024': {'kegg_id': 24, 'name': 'acetyl-CoA', 'node': 24, 'vis': 1, 'wt': 1},
 ... }

En mi caso, quería hacer lo mismo pero con columnas seleccionadas del marco de datos de Pandas, por lo que necesitaba cortar las columnas. Hay dos enfoques.

  1. Directamente:

(ver: Convertir pandas a diccionario definiendo las columnas utilizadas para los valores clave )

node_df.set_index('kegg_cid')[['name', 'wt', 'vis']].T.to_dict('dict')

{'c00022': {'name': 'pyruvate', 'vis': 1, 'wt': 1},
 'c00024': {'name': 'acetyl-CoA', 'vis': 1, 'wt': 1},
 ... }
  1. "Indirectamente:" primero, corte las columnas / datos deseados del marco de datos Pandas (nuevamente, dos enfoques),
node_df_sliced = node_df[['kegg_cid', 'name', 'wt', 'vis']]

o

node_df_sliced2 = node_df.loc[:, ['kegg_cid', 'name', 'wt', 'vis']]

que luego puede usarse para crear un diccionario de diccionarios

node_df_sliced.set_index('kegg_cid').T.to_dict('dict')

{'c00022': {'name': 'pyruvate', 'vis': 1, 'wt': 1},
 'c00024': {'name': 'acetyl-CoA', 'vis': 1, 'wt': 1},
 ... }
Victoria Stuart
fuente
-1

DataFrame.to_dict() convierte DataFrame a diccionario.

Ejemplo

>>> df = pd.DataFrame(
    {'col1': [1, 2], 'col2': [0.5, 0.75]}, index=['a', 'b'])
>>> df
   col1  col2
a     1   0.1
b     2   0.2
>>> df.to_dict()
{'col1': {'a': 1, 'b': 2}, 'col2': {'a': 0.5, 'b': 0.75}}

Consulte esta documentación para más detalles.

Umer
fuente
2
Sí, pero el OP explícito declaró que quieren que los índices de las filas sean las claves, no las etiquetas de las columnas.
Vicki B