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



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

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

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

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

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

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


7

Anda bisa menggunakan 'dikt pemahaman'

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

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

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)

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.

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


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)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.