Python pandas veri çerçevesinden sözlüğe


111

İki sütunlu bir veri çerçevem ​​var ve bunu python sözlüğüne dönüştürmeyi planlıyorum - ilk sütun anahtar ve ikincisi değer olacak. Şimdiden teşekkür ederim.

Veri çerçevesi:

    id    value
0    0     10.2
1    1      5.7
2    2      7.4



4
@perigee: Soruyu çözüldü olarak işaretlemek için cevaplardan birini (yardımcı oluyorsa) kabul edebilir misiniz? Bu, diğer kullanıcılara da yardımcı olacaktır.
MERose

Dizinle eşleşen bir kimliğiniz varsa, onu dizin olarak ayarlamalısınız.
Faris

Yanıtlar:


152

İçin dokümanlara bakın to_dict. Bunu şu şekilde kullanabilirsiniz:

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

Ve tek bir sütununuz varsa, sütun adından kaçınmak için diktedeki bir düzey de olur (aslında bu durumda kullanırsınız Series.to_dict()):

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

14
Kimlik sütunlarında fazlalık değerler varsa bu komutun veri kaybedeceğini unutmayın: >>> ptest = p.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) >>> ptest.set_index('id')['value'].to_dict()
dalloliogm

9
Söylemeliyim ki, bu dokümanlar bağlantısında bana bu sorunun cevabını verecek hiçbir şey yok.
Ben Fulton

@bombayquant aşağıdaki DSM'leri ve cevaplarımı görün. Bunun 4 yıllık bir tartışma olduğunu unutmayın.
dalloliogm

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

1
Not: dizinin istenen sözlük anahtarı olması durumunda, şunu yapın: dict (zip (df.index, df.value))
aLbAc

48

Yinelenenleri korumanın basit bir yolunu istiyorsanız, şunları kullanabilirsiniz 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
Güzel ve zarif bir çözüm, ancak 50 bin satırlık bir tabloda, aşağıdaki çirkin çözümümden yaklaşık 6 kat daha yavaş.
dalloliogm

@dalloliogm: bunun için bir örnek tablo verebilir misiniz? Bir Python döngüsünden altı kat daha yavaşsa, pandalarda bir performans hatası olabilir.
DSM

23

Bu ileti dizisindeki joris ve yinelenen ileti dizisindeki punchagan tarafından verilen yanıtlar çok zariftir, ancak anahtarlar için kullanılan sütun herhangi bir yinelenen değer içeriyorsa doğru sonuçları vermeyecektir.

Örneğin:

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

Yinelenen girişleriniz varsa ve bunları kaybetmek istemiyorsanız, bu çirkin ama çalışan kodu kullanabilirsiniz:

>>> 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
Yorumlarda bir blok olmaması nedeniyle biçimlendirmeyi mydict = defaultdict(list)\n for (key, val) in ptest[["id", "value"]].itertuples(index=False):\n mydict[key].append(val)
Midnighter

1
Tek astar kadar şık olmasa da çözümünüzü daha çok beğendim.
Peter Maguire

9

En basit çözüm:

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

Misal:

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

Val1, val2, val3, vb. Gibi birden çok değeriniz varsa ve bunları liste olarak istiyorsanız, aşağıdaki kodu kullanın:

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

1
recordsburada ne anlama geliyor?
mingchau

1
@mingchau recordsburada ortalama ‘records’ : list like [{column -> value}, … , {column -> value}] bakın pandas.pydata.org/pandas-docs/stable/reference/api/...
AmuletxHeart

8

bazı sürümlerde aşağıdaki kod çalışmayabilir

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

bu yüzden açık yap

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

Not kelime kimliği ayrılmış kelime olduğu i id_ kullanılan


7

'Dikte anlama' kullanabilirsiniz

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

Pandalarla döngü yapmak, bellek kullanımı açısından en verimli yöntem değildir. Bakınız: engineering.upside.com/…
tda

OP en etkili cevabı istemedi, bu yüzden @ Dongwan Kim güzel bir alternatif çözüm sundu.
Bir ekonomist

3

Yinelenen girişleri kaybetmemek için başka bir (biraz daha kısa) çözüm:

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

Sözlük değeri olarak bir listeye ihtiyacınız var. Bu kod hile yapacak.

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

1

Bu soruyu üç taneden sözlük yapmaya çalışırken buldum pandalar veri sütunundan buldum. Benim durumumda, veri çerçevesinin A, B ve C sütunları vardır (diyelim ki A ve B boylam ve enlemin coğrafi koordinatlarıdır ve C, aşağı yukarı durum olan ülke bölgesi / eyalet / vb.).

Her bir A, B değeri çifti (sözlük anahtarı) karşılık gelen satırdaki C (sözlük değeri) değeriyle eşleşen bir sözlük istedim (her A, B değeri çiftinin önceki filtreleme nedeniyle benzersiz olması garanti edildi, ancak Bu bağlamda farklı A, B değerleri çiftleri için aynı C değerine sahip olmak mümkün), ben de yaptım:

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

Pandaların to_dict () kullanılması da işe yarar :

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

(Sözlüğü oluşturan satırı çalıştırmadan önce A veya B sütunlarından hiçbiri dizin olarak kullanılmadı)

Her iki yaklaşım da hızlıdır (85.000 satırlı bir veri çerçevesinde bir saniyeden az, 5 yıllık hızlı çift çekirdekli dizüstü bilgisayar).

Bunu göndermemin nedenleri:

  1. bu tür bir çözüme ihtiyaç duyanlar için
  2. Eğer birisi daha hızlı çalışan bir çözüm biliyorsa (örneğin, milyonlarca satır için), bir yanıt almak isterim.

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

bu benim eğimim, temel bir döngü


0

Bu benim çözümüm:

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.