基于3个数据帧列的嵌套字典

问题描述 投票:0回答:1

我试图建立一个基于3个pandas df列的嵌套字典:

dataframe:停止列:'direction'(1-2),'stop_num'(如果方向为1则为1-23,如果方向为2则为100-2300),'name_eng'

我想要做的是:

zip中的x,y,z的dct = {x:{y:z}(停止['方向'],停止['name_eng'],停止['stop_num'])}

我得到的结果确实是一个嵌套字典,但由于未知原因我只得到y:z中的最后一个值,所以字典看起来像:

{1:{1:'aaa'},'2:{100:'bbb'}}

知道我做错了什么吗?我需要的是一个嵌套字典,每个方向都有两个字典。

谢谢!

python-3.x dictionary dictionary-comprehension
1个回答
0
投票

想象一下你的专栏是:

1   a   1a
1   b   1b
2   a   2a
2   b   2b

现在,试试你的代码:

>>> {x: {y:z} for x, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b'])}
{1: {'b': '1b'}, 2: {'b': '2b'}}

你对元组有一个循环:(1, 'a', '1a'), (1, 'b', '1b'), (2, 'a', '2a'), (2, 'b', '2b')

元组的第一个元素是字典的“主”键。因此,在第一个元组之后,dict是{1: {'a':'1a'}}

然后是(1, 'b', '1b')。主键1的值被覆盖,dict变为:{1: {'b':'1b'}}

接下来的步骤是:{1: {'b':'1b'}, 2: {'a': '2a'}}{1: {'b': '1b'}, 2: {'b': '2b'}}

为避免覆盖,您可以:

>>> d = {}
>>> for x, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b']):
...     d.setdefault(x, {}).update({y:z})
... 
>>> d
{1: {'a': '1a', 'b': '1b'}, 2: {'a': '2a', 'b': '2b'}}

我们的想法是为每个新的主键(setdefault(..., {}))创建一个新的dict,并更新与主键(update({y:z}))相关的dict。

如果你想要一个词典理解,这个将工作:

>>> {x: {y:z for k, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b']) if k==x} for x in set([1,1,2,2])}
{1: {'a': '1a', 'b': '1b'}, 2: {'a': '2a', 'b': '2b'}}

但它的效率远远低于for循环,因为你在第一列上循环一次以获得主键,然后在所有行上循环,为每个主键循环。

© www.soinside.com 2019 - 2024. All rights reserved.