python panda dataframe al dizionario


111

Ho un dataframe a due colonne e intendo convertirlo nel dizionario Python: la prima colonna sarà la chiave e la seconda il valore. Grazie in anticipo.

dataframe:

    id    value
0    0     10.2
1    1      5.7
2    2      7.4



4
@perigeo: puoi forse accettare una delle risposte (se utile) per contrassegnare la domanda come risolta? Questo aiuterà anche altri utenti.
— MERose

se hai un id che corrisponde all'indice dovresti impostarlo come index.
— Faris

Risposte:


152

Vedi i documenti per to_dict. Puoi usarlo in questo modo:

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

E se hai solo una colonna, per evitare il nome della colonna è anche un livello nel dict (in realtà, in questo caso usi il Series.to_dict()):

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

14
Nota che questo comando perderà i dati se ci sono valori ridondanti nelle colonne ID: >>> ptest = p.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) >>> ptest.set_index('id')['value'].to_dict()
— dalloliogm

9
Devo dire che non c'è niente in quel link alla documentazione che mi avrebbe dato la risposta a questa domanda.
— Ben Fulton

@bombayquant vedi DSM e le mie risposte di seguito. Nota che questa è una discussione vecchia di 4 anni.
— dalloliogm il

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

1
Nota: nel caso in cui l'indice sia la chiave del dizionario desiderata, eseguire: dict (zip (df.index, df.value))
— aLbAc

47

Se vuoi un modo semplice per conservare i duplicati, potresti usare 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
Soluzione bella ed elegante, ma su una tabella di 50k righe è circa 6 volte più lenta della mia brutta soluzione qui sotto.
— dalloliogm

@dalloliogm: potresti fornire una tabella di esempio che accade per? Se è sei volte più lento di un ciclo Python, potrebbe esserci un bug di prestazioni nei panda.
— DSM

23

Le risposte di joris in questo thread e di punchagan nel thread duplicato sono molto eleganti, tuttavia non daranno risultati corretti se la colonna usata per le chiavi contiene un valore duplicato.

Per esempio:

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

Se hai voci duplicate e non vuoi perderle, puoi usare questo codice brutto ma funzionante:

>>> 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
Scusa la formattazione per la mancanza di un blocco nei commenti:mydict = defaultdict(list)\n for (key, val) in ptest[["id", "value"]].itertuples(index=False):\n mydict[key].append(val)
— Midnighter

1
Sebbene non sia elegante come una battuta, mi è piaciuta molto di più la tua soluzione.
— Peter Maguire

9

Soluzione più semplice:

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

Esempio:

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

Se hai più valori, come val1, val2, val3, ecc e li vuoi come elenchi, usa il codice seguente:

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

1
cosa recordssignifica qui?
— mingchau

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

8

in alcune versioni il codice seguente potrebbe non funzionare

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

quindi rendilo esplicito

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

Nota che ho usato id_ perché la parola id è una parola riservata


7

Puoi usare la "comprensione dettata"

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

Il looping con i panda non è il più efficiente in termini di utilizzo della memoria. Vedi: engineering.upside.com/…
— tda

OP non ha chiesto la risposta più efficiente, quindi penso che @Dongwan Kim abbia fornito una buona soluzione alternativa.
— Un economista

3

Un'altra soluzione (leggermente più breve) per non perdere voci duplicate:

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

Hai bisogno di un elenco come valore del dizionario. Questo codice farà il trucco.

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

1

Ho trovato questa domanda mentre cercavo di creare un dizionario con tre colonne di un dataframe dei panda. Nel mio caso il dataframe ha le colonne A, B e C (diciamo che A e B sono le coordinate geografiche di longitudine e latitudine e C la regione / stato / ecc del paese, che è più o meno il caso).

Volevo un dizionario con ogni coppia di valori A, B (chiave del dizionario) corrispondente al valore di C (valore del dizionario) nella riga corrispondente (ogni coppia di valori A, B è garantita come unica a causa del filtraggio precedente, ma lo è possibile avere lo stesso valore di C per diverse coppie di valori A, B in questo contesto), quindi ho fatto:

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

Usare i panda to_dict () funziona anche:

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

(nessuna delle colonne A o B è stata utilizzata come indice prima di eseguire la riga di creazione del dizionario)

Entrambi gli approcci sono veloci (meno di un secondo su un dataframe con 85.000 righe, laptop dual-core veloce di 5 anni).

I motivi per cui sto postando questo:

  1. per chi necessita di questo tipo di soluzione
  2. se qualcuno conosce una soluzione di esecuzione più veloce (ad esempio, per milioni di righe), apprezzerei una risposta.

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

questa è la mia mossa, un ciclo di base


0

Questa è la mia soluzione:

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