python pandas dataframe到字典


111

我有两列数据框,打算将其转换为python字典-第一列将是键,第二列将是值。先感谢您。

数据框:

    id    value
0    0     10.2
1    1      5.7
2    2      7.4



4
@perigee:您能否接受其中一个答案(如果有帮助),以将问题标记为已解决?这也将对其他用户有所帮助。
MERose '16

如果您的ID与索引匹配,则应将其设置为index。
法里斯

Answers:


152

请参阅有关的文档to_dict。您可以像这样使用它:

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

如果只有一列,为避免列名也是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 2014年

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循环慢六倍,则可能是熊猫存在性能错误。
DSM 2014年

23

此线程中的joris和重复的线程中的punchagan的答案非常好,但是,如果用于键的列包含任何重复的值,它们将不会给出正确的结果。

例如:

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

1
虽然不像单线纸那样优雅,但我更喜欢您的解决方案。
Peter Maguire'3

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
@mingchau records这里平均‘records’ : list like [{column -> value}, … , {column -> value}]pandas.pydata.org/pandas-docs/stable/reference/api/...
AmuletxHeart

8

在某些版本中,以下代码可能无法正常工作

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

所以要明确

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

注意我使用id_,因为单词id是保留单词


7

您可以使用“字典理解”

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

我试图从熊猫数据框的列中制作字典时发现了这个问题。在我的情况下,数据框具有A,B和C列(假设A和B是经度和纬度的地理坐标,C则是国家/地区/州/等等,或多或少是这种情况)。

我想要一个字典,其中每对A,B值(字典键)与对应行中的C(字典值)的值匹配(由于先前的过滤,每 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列均未用作索引)

两种方法都非常快速(在具有8万行,具有5年历史的快速双核笔记本电脑上,数据帧不到一秒钟)。

我发布此消息的原因:

  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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.