Converti un Pandas DataFrame in un dizionario


168

Ho un DataFrame con quattro colonne. Voglio convertire questo DataFrame in un dizionario Python. Voglio che siano gli elementi della prima colonna keyse gli elementi di altre colonne nella stessa riga values.

dataframe:

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

L'output dovrebbe essere così:

Dizionario:

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

4
Dataframe.to_dict()?
Anzel,

3
Dataframe.to_dict()produrrà A,B,Cle chiavi invece dip,q,r
Prince Bhatti,

@jezrael come ottenere il seguente output? {2: {'p': [1,3]}, 2: {'q': [4,3]}, 9: {'r': [4,0]}} per lo stesso set di dati?
Panda,

@jezrael equivalenti di colonna della domanda precedente {'c': {'ID': 'A', 'B'}}
panda

Risposte:


338

Il to_dict()metodo imposta i nomi delle colonne come chiavi del dizionario, quindi dovrai rimodellare leggermente DataFrame. Impostare la colonna "ID" come indice e quindi trasporre DataFrame è un modo per raggiungere questo obiettivo.

to_dict()accetta anche un argomento 'orient' che ti servirà per produrre un elenco di valori per ogni colonna. In caso contrario, {index: value}verrà restituito un dizionario del modulo per ogni colonna.

Questi passaggi possono essere eseguiti con la seguente riga:

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

Nel caso in cui sia necessario un diverso formato del dizionario, ecco alcuni esempi dei possibili argomenti orient. Considera il seguente semplice DataFrame:

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

Quindi le opzioni sono le seguenti.

dict - l'impostazione predefinita: i nomi delle colonne sono chiavi, i valori sono dizionari dell'indice: coppie di dati

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

elenco : le chiavi sono nomi di colonna, i valori sono elenchi di dati di colonna

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

serie - come 'list', ma i valori sono 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 : suddivide colonne / dati / indice come chiavi con valori che sono rispettivamente nomi di colonna, valori di dati per riga e etichette di indice

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

record : ogni riga diventa un dizionario in cui la chiave è il nome della colonna e il valore sono i dati nella cella

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

indice - come "record", ma un dizionario di dizionari con chiavi come etichette di indice (anziché un elenco)

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

14
questo sarà un esempio:df.set_index('ID').T.to_dict('list')
Anzel,

1
Per un record in Data Frame. df.T.to_dict () [0]
kamran kausar

23

Prova ad usare 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

Produzione:

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

21

Segui questi passi:

Supponiamo che il tuo frame di dati sia il seguente:

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

1. Utilizzare set_indexper impostare le IDcolonne come indice del frame di dati.

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

2. Utilizzare il orient=indexparametro per disporre l'indice come chiavi del dizionario.

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

I risultati saranno i seguenti:

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

3. Se è necessario disporre di ciascun campione come elenco, eseguire il codice seguente. Determina l'ordine delle colonne

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]

2
Per l'ultimo bit sembra che saresti più semplice usando una comprensione dict per sostituire la comprensione for loop + list (3 righe -> 1). Ad ogni modo, anche se è bello avere opzioni, la risposta migliore è molto più breve.
fantastico

Questo è utile perché spiega chiaramente come utilizzare una colonna o un'intestazione specifica come indice.
Tropicalrambler

10

Se non ti dispiace che i valori del dizionario siano tuple, puoi usare itertuples:

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

7

dovrebbe un dizionario come:

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

essere richiesto da un frame di dati come:

        a      b
0     red  0.500
1  yellow  0.250
2    blue  0.125

Il modo più semplice sarebbe fare:

dict(df.values.tolist())

snippet di lavoro di seguito:

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

inserisci qui la descrizione dell'immagine


2

Per il mio uso (nomi dei nodi con posizioni xy) ho trovato la risposta di @ user4179775 al più utile / intuitivo:

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

appendice

In seguito sono tornato su questo problema, per altri, ma correlati, lavori. Ecco un approccio che rispecchia più da vicino la risposta [eccellente] accettata.

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

Converti il ​​frame di dati di Panda in un [elenco], {dict}, {dict of {dict}}, ...

Per risposta accettata:

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

Nel mio caso, volevo fare la stessa cosa, ma con colonne selezionate dal frame di dati Pandas, quindi avevo bisogno di tagliare le colonne. Esistono due approcci.

  1. Direttamente:

(vedi: Converti i panda in dizionario definendo le colonne utilizzate per i valori chiave )

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. "Indirettamente:" per prima cosa, tagliare le colonne / i dati desiderati dal dataframe di Pandas (di nuovo, due approcci),
node_df_sliced = node_df[['kegg_cid', 'name', 'wt', 'vis']]

o

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

che può quindi essere utilizzato per creare un dizionario di dizionari

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

-1

DataFrame.to_dict() converte DataFrame in dizionario.

Esempio

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

Vedere questa documentazione per i dettagli


2
Sì, ma l'OP esplicito ha dichiarato che vogliono che gli indici di riga siano le chiavi, non le etichette delle colonne.
Vicki B,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.