Convertir un DataFrame Pandas en dictionnaire

168

J'ai un DataFrame avec quatre colonnes. Je souhaite convertir ce DataFrame en dictionnaire python. Je veux que les éléments de la première colonne soient keyset les éléments des autres colonnes de la même ligne soient values.

Trame de données:

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

La sortie devrait être comme ceci:

Dictionnaire:

{'p': [1,3,2], 'q': [4,3,2], 'r': [4,0,9]}
Prince Bhatti
la source
4
Dataframe.to_dict()?
Anzel
3
Dataframe.to_dict()fera A,B,Cles clés à la place dep,q,r
Prince Bhatti
@jezrael comment obtenir la sortie suivante? {2: {'p': [1,3]}, 2: {'q': [4,3]}, 9: {'r': [4,0]}} pour le même ensemble de données?
panda
@jezrael équivalents de la colonne de la question ci-dessus {'c': {'ID': 'A', 'B'}}
panda

Réponses:

338

La to_dict()méthode définit les noms de colonne comme des clés de dictionnaire, vous devrez donc légèrement remodeler votre DataFrame. Définir la colonne 'ID' comme index, puis transposer le DataFrame est un moyen d'y parvenir.

to_dict()accepte également un argument «orient» dont vous aurez besoin pour afficher une liste de valeurs pour chaque colonne. Sinon, un dictionnaire de la forme {index: value}sera retourné pour chaque colonne.

Ces étapes peuvent être effectuées avec la ligne suivante:

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

Dans le cas où un format de dictionnaire différent est nécessaire, voici des exemples des arguments d'orientation possibles. Considérez le DataFrame simple suivant:

>>> 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

Ensuite, les options sont les suivantes.

dict - la valeur par défaut: les noms de colonne sont des clés, les valeurs sont des dictionnaires d'index: paires de données

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

list - les clés sont des noms de colonnes, les valeurs sont des listes de données de colonnes

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

series - comme 'list', mais les valeurs sont 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}

split - divise les colonnes / données / index sous forme de clés avec les valeurs correspondant aux noms de colonnes, les valeurs de données par ligne et les étiquettes d'index respectivement

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

records - chaque ligne devient un dictionnaire où la clé est le nom de la colonne et la valeur les données de la cellule

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

index - comme 'records', mais un dictionnaire de dictionnaires avec des clés comme étiquettes d'index (plutôt qu'une liste)

>>> df.to_dict('index')
{0: {'a': 'red', 'b': 0.5},
 1: {'a': 'yellow', 'b': 0.25},
 2: {'a': 'blue', 'b': 0.125}}
Alex Riley
la source
14
ce sera une ligne:df.set_index('ID').T.to_dict('list')
Anzel
1
Pour un enregistrement dans le bloc de données. df.T.to_dict () [0]
kamran kausar
23

Essayez d'utiliser 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

Production:

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

la source
21

Suivez ces étapes:

Supposons que votre dataframe soit la suivante:

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

1. Utilisez set_indexpour définir les IDcolonnes comme index de trame de données.

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

2. Utilisez le orient=indexparamètre pour avoir l'index comme clé de dictionnaire.

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

Les résultats seront les suivants:

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

3. Si vous devez avoir chaque exemple sous forme de liste, exécutez le code suivant. Déterminez l'ordre des colonnes

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
la source
2
Pour le dernier bit semble que vous seriez plus simple d'utiliser une compréhension de dictée pour remplacer la boucle for + compréhension de liste (3 lignes -> 1). Quoi qu'il en soit, bien qu'il soit agréable d'avoir des options, la réponse principale est beaucoup plus courte.
fantastique
Ceci est pratique car il explique clairement comment utiliser une colonne ou un en-tête spécifique comme index.
Tropicalrambler
10

Si cela ne vous dérange pas que les valeurs du dictionnaire soient des tuples, vous pouvez utiliser 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
la source
7

devrait un dictionnaire comme:

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

être requis hors d'un dataframe comme:

        a      b
0     red  0.500
1  yellow  0.250
2    blue  0.125

Le moyen le plus simple serait de faire:

dict(df.values.tolist())

extrait de code ci-dessous:

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

entrez la description de l'image ici

Muhammad Moiz Ahmed
la source
2

Pour mon utilisation (noms de nœuds avec des positions xy), j'ai trouvé la réponse de @ user4179775 à la plus utile / intuitive:

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),
 ... }

Addenda

Je suis revenu plus tard sur cette question, pour d'autres travaux, mais liés. Voici une approche qui reflète de plus près la [excellente] réponse acceptée.

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
...

Convertir la trame de données Pandas en [liste], {dict}, {dict of {dict}}, ...

Par réponse acceptée:

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},
 ... }

Dans mon cas, je voulais faire la même chose mais avec des colonnes sélectionnées du dataframe Pandas, donc j'avais besoin de découper les colonnes. Il existe deux approches.

  1. Directement:

(voir: Convertir les pandas en dictionnaire définissant les colonnes utilisées pour les valeurs clés )

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. "Indirectement:" découpez d'abord les colonnes / données souhaitées à partir du dataframe Pandas (encore une fois, deux approches),
node_df_sliced = node_df[['kegg_cid', 'name', 'wt', 'vis']]

ou

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

qui peut ensuite être utilisé pour créer un dictionnaire de dictionnaires

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
la source
-1

DataFrame.to_dict() convertit DataFrame en dictionnaire.

Exemple

>>> 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}}

Consultez cette documentation pour plus de détails

Umer
la source
2
Oui, mais l'OP explicite a déclaré qu'il voulait que les index de ligne soient les clés, pas les étiquettes de colonne.
Vicki B