python pandas dataframe ke kamus

111

Saya memiliki dataframe dua kolom, dan bermaksud untuk mengubahnya menjadi kamus python - kolom pertama akan menjadi kuncinya dan yang kedua akan menjadi nilainya. Terima kasih sebelumnya.

Dataframe:

    id    value
0    0     10.2
1    1      5.7
2    2      7.4
perigee
sumber
kemungkinan duplikat: stackoverflow.com/questions/18012505/…
dalloliogm
sudahkah
user2290820
4
@perigee: Dapatkah Anda menerima salah satu jawaban (jika membantu) untuk menandai pertanyaan sebagai terselesaikan? Ini akan membantu pengguna lain juga.
MERose
jika Anda memiliki id yang cocok dengan indeks, Anda harus mengaturnya sebagai indeks.
Faris

Jawaban:

152

Lihat dokumen untuk to_dict. Anda bisa menggunakannya seperti ini:

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

Dan jika Anda hanya memiliki satu kolom, untuk menghindari nama kolom juga merupakan tingkat di dict (sebenarnya, dalam hal ini Anda menggunakan Series.to_dict()):

df.set_index('id')['value'].to_dict()
joris
sumber
14
Perhatikan bahwa perintah ini akan kehilangan data jika ada nilai yang berlebihan di kolom ID: >>> ptest = p.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) >>> ptest.set_index('id')['value'].to_dict()
dalloliogm
9
Saya harus mengatakan, tidak ada apa pun di tautan dokumen itu yang akan memberi saya jawaban atas pertanyaan ini.
Ben Fulton
@bombayquant lihat DSM dan jawaban saya di bawah. Perhatikan bahwa ini adalah diskusi berusia 4 tahun.
dalloliogm
66
mydict = dict(zip(df.id, df.value))
praful gupta
sumber
1
Catatan: jika indeks adalah kunci kamus yang diinginkan, lakukan: dict (zip (df.index, df.value))
aLbAc
47

Jika Anda menginginkan cara sederhana untuk mempertahankan duplikat, Anda dapat menggunakan 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]}
DSM
sumber
1
Solusi bagus dan elegan, tetapi pada tabel baris 50k, ini sekitar 6 kali lebih lambat dari solusi jelek saya di bawah ini.
dalloliogm
@dalloliogm: dapatkah Anda memberikan contoh tabel yang terjadi? Jika enam kali lebih lambat dari loop Python, mungkin ada bug kinerja di pandas.
DSM
23

Jawaban joris di utas ini dan jawaban punchagan di utas duplikat sangat elegan, namun tidak akan memberikan hasil yang benar jika kolom yang digunakan untuk kunci berisi nilai duplikat.

Sebagai contoh:

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

Jika Anda memiliki entri duplikat dan tidak ingin kehilangannya, Anda dapat menggunakan kode jelek tapi berfungsi ini:

>>> 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]}
dalloliogm.dll
sumber
2
Maafkan format karena kurangnya blok di komentar:mydict = defaultdict(list)\n for (key, val) in ptest[["id", "value"]].itertuples(index=False):\n mydict[key].append(val)
Midnighter
1
Meskipun tidak seanggun one-liner, saya lebih menyukai solusi Anda.
Peter Maguire
9

Solusi paling sederhana:

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

Contoh:

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

Jika Anda memiliki beberapa nilai, seperti val1, val2, val3, dll dan Anda menginginkannya sebagai daftar, gunakan kode di bawah ini:

df.set_index('id').T.to_dict('list')
Gil Baggio
sumber
1
apa recordsmaksudnya disini?
mingchau
1
@mingchau di recordssini maksud ‘records’ : list like [{column -> value}, … , {column -> value}] Lihat pandas.pydata.org/pandas-docs/stable/reference/api/…
AmuletxHeart
8

di beberapa versi, kode di bawah ini mungkin tidak berfungsi

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

jadi buatlah itu eksplisit

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

Perhatikan saya menggunakan id_ karena kata id adalah kata yang dipesan

Vincent Appiah
sumber
7

Anda bisa menggunakan 'dikt pemahaman'

my_dict = {row[0]: row[1] for row in df.values}
Dongwan Kim
sumber
Pengulangan dengan panda bukanlah yang paling efisien dalam hal penggunaan memori. Lihat: engineering.upside.com/…
tda
OP tidak meminta jawaban yang paling efisien jadi saya pikir @Dongwan Kim memberikan solusi alternatif yang bagus.
Seorang ekonom
3

Solusi lain (sedikit lebih pendek) untuk tidak kehilangan entri duplikat:

>>> 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]}
pengguna1376377
sumber
1

Anda membutuhkan daftar sebagai nilai kamus. Kode ini akan melakukan triknya.

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

Saya menemukan pertanyaan ini saat mencoba membuat kamus dari tiga kolom kerangka data panda. Dalam kasus saya kerangka data memiliki kolom A, B dan C (katakanlah A dan B adalah koordinat geografis dari bujur dan lintang dan C wilayah negara / negara bagian / dll, yang kurang lebih demikian).

Saya ingin kamus dengan setiap pasangan nilai A, B (kunci kamus) cocok dengan nilai C (nilai kamus) di baris yang sesuai (setiap pasangan nilai A, B dijamin unik karena pemfilteran sebelumnya, tetapi ini adalah mungkin memiliki nilai C yang sama untuk pasangan nilai A, B yang berbeda dalam konteks ini), jadi saya lakukan:

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

Menggunakan pandas to_dict () juga berfungsi:

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

(tidak ada kolom A atau B yang digunakan sebagai indeks sebelum menjalankan baris yang membuat kamus)

Kedua pendekatan tersebut cepat (kurang dari satu detik pada kerangka data dengan 85 ribu baris, laptop dual-core cepat berusia 5 tahun).

Alasan saya memposting ini:

  1. bagi mereka yang membutuhkan solusi semacam ini
  2. jika seseorang mengetahui solusi eksekusi yang lebih cepat (misalnya, untuk jutaan baris), saya akan menghargai balasannya.
Alexandre Dias
sumber
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

ini sloution saya, loop dasar

SummersKing
sumber
0

Ini solusi saya:

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)
Hamoon
sumber