如何将数据框转换为字典

190

我有一个包含两列的数据框,我打算将其转换为字典。第一列将成为键,第二列将成为值。

数据框:

    id    value
0    0     10.2
1    1      5.7
2    2      7.4

我该怎么做?

21个回答

398
如果lakes是您的DataFrame,您可以这样做
area_dict = dict(zip(lakes.id, lakes.value))

42
解决方案:area_dict = dict(zip(lakes['id'], lakes['value'])) 的意思是将 lakes 数据集中的 idvalue 列组合成一个字典 area_dict。翻译完成,无其他内容。 - jezrael
3
如果您想要字典值中有多列,该怎么办?我在考虑像这样的代码:area_dict = dict(zip(lakes.area, (lakes.count, lakes.other_column)))。您该如何实现它? - jesseaam
6
如果第二个参数有多个值,这样做是行不通的。 - pnv

214

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

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

如果你只有一个列,为了避免列名也成为字典中的一个键(实际上,在这种情况下你可以使用 Series.to_dict()):

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

26
请注意,如果ID列中存在冗余值,则此命令将丢失数据:`>>> ptest = p.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value'])
ptest.set_index('id')['value'].to_dict()`
- dalloliogm
13
我必须说,那个文档链接里没有任何东西可以回答这个问题。 - Ben Fulton

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

4
注意:如果索引是所需的字典键,则执行以下操作:dict(zip(df.index,df.value)) - aLbAc

68

如果你想简单地保留重复项,可以使用 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]}

2
优美而简洁的解决方案,但在一个5万行的表格上,它比我下面那个丑陋的解决方案慢了大约6倍。 - dalloliogm
@dalloliogm:你能给一个出现这种情况的例子吗?如果比Python循环慢了六倍,那么pandas可能存在性能问题。 - DSM

34

这个问题在这个帖子里 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]}

3
请原谅评论区没有代码块的格式:mydict = defaultdict(list)\n for (key, val) in ptest[["id", "value"]].itertuples(index=False):\n mydict[key].append(val) - Midnighter

15

我认为以下是最简单的解决方案:

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

在上面的链接中了解有关记录的更多信息: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_dict.html


13

使用pandas可以这样做:

如果lakes是你的DataFrame:

area_dict = lakes.to_dict('records')

1
在给定的例子中没有“records”列。此时索引将成为键,这不是我们想要的。 - Michael D
20
@MichaelD 'records' 不是一列。它是参数 orient 的一个选项。 - Zheng Liu
12
实际上,这将输出一个由字典组成的列表,格式如下: [{'area': 10, 'count': 7}, {'area': 20, 'count': 5}...]而不是一个键值对字典。 - Roei Bahumi

13
你可以使用“字典推导式”。
my_dict = {row[0]: row[1] for row in df.values}

1
使用pandas循环并不是在内存使用方面最有效的。请参见:https://engineering.upside.com/a-beginners-guide-to-optimizing-pandas-code-for-speed-c09ef2c6a4d6 - tda

9

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

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

因此,要明确表达

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

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


同意,它对我也没有用。但是你怎么能做到 df.id,因为列名 id 不被识别为数据框变量,对吧?就像写入数据框对象库中的变量一样。我一定是误解了什么。 - Azurespot

6
这是一个将具有三列A、B和C的数据框转换的示例(假设A和B是经度和纬度的地理坐标,C是国家/地区/州等)。
我希望获得一个字典,其中每个A、B值对应一个C值(字典值)在相应的行中(由于之前的过滤,每个A、B值对保证是唯一的,但在此情况下,可能会存在不同的A、B值对应相同的C值),因此我将执行以下操作:
mydict = dict(zip(zip(df['A'],df['B']), df['C']))

使用Pandas的 to_dict() 也可以:

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

在创建字典的那行代码执行之前,A或B列都没有被用作索引。

这两种方法都很快(在一台约2015年快速双核笔记本电脑上处理具有85k行的数据框时少于1秒)。


“快速双核笔记本电脑”是什么?最好将该行删除或替换为特定的笔记本电脑和CPU型号。让我们自己决定它是否“快速”。 - TylerH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接