python pandas dataframe to辞書


111

私は2列のデータフレームを持っているので、それをpython辞書に変換するつもりです。最初の列がキーになり、2番目の列が値になります。前もって感謝します。

データフレーム:

    id    value
0    0     10.2
1    1      5.7
2    2      7.4


あなたはこのアウト?:チェックしていpandas.pydata.org/pandas-docs/dev/generated/...
user2290820

4
@perigee:回答の1つ(役立つ場合)を受け入れて、質問を解決済みとしてマークできますか?これは他のユーザーにも役立ちます。
MERose

インデックスに一致するIDがある場合は、それをインデックスとして設定する必要があります。
ファリス2017

回答:


151

のドキュメントを参照してくださいto_dict。次のように使用できます。

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

列が1つしかない場合は、列名がdictのレベルでもないようにします(実際には、この場合はを使用しますSeries.to_dict())。

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

14
:ID列であっ冗長値ならば、このコマンドはデータが失われることに注意してください >>> ptest = p.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) >>> ptest.set_index('id')['value'].to_dict()
dalloliogm

9
そのドキュメントリンクには、この質問に対する答えを提供してくれるものは何もありません。
ベン・フルトン

@bombayquantは、以下のDSMと私の回答を参照してください。これは4年前の議論です。
dalloliogm

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

1
注:インデックスが目的のディクショナリキーである場合は、次のようにします。dict(zip(df.index、df.value))
aLbAc

47

重複を保存する簡単な方法が必要な場合は、次を使用できます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
洗練されたエレガントなソリューションですが、5万行のテーブルでは、以下の醜いソリューションよりも約6倍遅くなります。
dalloliogm 2014年

@dalloliogm:発生するテーブルの例を教えてください。Pythonループより6倍遅い場合は、パンダにパフォーマンスのバグがある可能性があります。
DSM 2014年

23

このスレッドのjorisと複製されたスレッドのパンチガンによる回答は非常に洗練されていますが、キーに使用される列に重複する値が含まれていると、正しい結果が得られません。

例えば:

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

重複したエントリがあり、それらを失いたくない場合は、次の醜いが機能するコードを使用できます。

>>> 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
コメントにブロックがないため、書式設定を失礼:mydict = defaultdict(list)\n for (key, val) in ptest[["id", "value"]].itertuples(index=False):\n mydict[key].append(val)
Midnighter

1
ワンライナーほどエレガントではありませんが、私はあなたのソリューションがはるかに好きでした。
Peter Maguire 2017年

9

最も簡単なソリューション:

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

例:

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

val1、val2、val3などの複数の値があり、それらをリストとして使用する場合は、以下のコードを使用します。

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

1
recordsここではどういう意味ですか?
mingchau

1
recordsここで@mingchau とは、pandas.pydata.org / pandas‘records’ : list like [{column -> value}, … , {column -> value}]
docs

8

一部のバージョンでは、以下のコードが機能しない場合があります

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

だからそれを明示的にする

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

idという単語は予約語であるため、id_を使用したことに注意してください


7

「dict comprehension」を使用できます

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

パンダとのループは、メモリ使用量の点で最も効率的ではありません。参照:engineering.upside.com/...
TDA

OPは最も効率的な答えを求めなかったので、@ Dongwan Kimは素晴らしい代替ソリューションを提供したと思います。
エコノミスト

3

重複したエントリを失わないための別の(少し短い)解決策:

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

辞書値としてリストが必要です。このコードでうまくいきます。

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

1

パンダデータフレームの3つの列から辞書を作成しようとしたときに、この質問を見つけました。私の場合、データフレームには列A、B、Cがあります(AとBは経度と緯度の地理座標で、Cは国の地域/州などです)。

対応する行のC(ディクショナリ値)の値と一致するA、B値(ディクショナリキー)の各ペアが含まれるディクショナリが必要でした(A、B値の各ペアは、以前のフィルタリングにより一意であることが保証されていますが、このコンテキストでは、AとBの値の異なるペアに対して同じCの値を使用することができるため、次のようにしました。

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

パンダを使う to_dict()も機能します:

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

(ディクショナリを作成する行を実行する前に、列AもBもインデックスとして使用されていませんでした)

どちらのアプローチも高速です(85k行のデータフレーム、5年前の高速デュアルコアラップトップでは1秒未満)。

私がこれを投稿している理由:

  1. この種のソリューションを必要とする人のために
  2. 誰かがより高速な実行ソリューション(たとえば、数百万行)を知っている場合は、返信をいただければ幸いです。

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

これは私の中身、基本的なループです


0

これは私の解決策です:

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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.