【问题标题】:How to DUMP the values of multiple dictionaries to the columns of a 2D array?如何将多个字典的值转储到二维数组的列中?
【发布时间】:2016-02-05 10:49:21
【问题描述】:

我有一组 15 个 dicts,同时具有 intfloat 值。键当然没有排序。我想:

  • 填充一个大小为50x15的二维numpy数组,使dict1的值在第0列下对齐,dict2的值在第1列下对齐,依此类推。

然而,在这样做之前,我需要将 dict 键从最小到最大排序。

这就是二维数组的样子:

dict1  dict2  dict3  dict4  dict5  dict6  dictn
val    val    val    val    val    val    val
val    val    val    val    val    val    val

我可以在一个 for 循环中完成吗?或者我应该使用3 嵌套for 循环,类似于下一个代码块?如果是这样,我怎样才能前进到下一个dict

#do stuff 
for i in range(array.shape[0]):
        for j in range(array.shape[1]):
            for val in dict1.items():
               array[i][0]=dict1[val]
#do stuff

【问题讨论】:

  • 你能举例说明dicts 的样子吗? len 的所有 dicts 都是 50 吗?
  • dict 项共享示例输入?
  • dict1={'event1':3400,'event2': 2345, 'event3':7654, ...}。 @vk1011 是的,所有字典都有len 50

标签: python arrays for-loop numpy dictionary


【解决方案1】:

如果您将字典收集到如下列表中:

dicts = [dict1, dict2, dict3,...]

那么你可以这样做:

dataarray = np.zeros((50,15),float)
for i, adict in enumerate(dicts):
    values = current_dict.values()
    for j,value in enumerate(values):
           dataarray[i,j]= value

我使用enumerate 来获取索引号,因为它更Pythonic 和更简洁。但是如果dataarray 不够大就会有问题。

[i,j] 是索引二维数组元素的正确方法。

我修改的剪辑对键没有任何作用,所以我忽略了那些(到目前为止)。

再次阅读您的问题,我看到您想要对键进行排序。在这种情况下,我们需要使用:

   items = adict.items()
   # list of key,value pairs
   items.sort()  # may need to tweak sort parameters
   for j, (key, [value) in enumerate(items):
        dataarray[i,j] = value

我没有测试过这段代码,所以可能有一些错误。但大纲是正确的 - 我认为。

如果您需要在 dataarray 的行中匹配键,我们将不得不做更多的工作。


我会使用类似的表达式

max_dict_size = max([len(d) for d in dicts])

找到字典的最大大小,并相应地定义dataarray

我突然想到,我不需要迭代来将字典值添加到数组中。我会用一本简单的字典来说明:

In [111]: dd={1:2.,3:4.,4:324.23}   # sample dictionary

In [112]: data=np.zeros((5,2),dtype=float)  # empty array

In [113]: items=dd.items()
In [114]: items
Out[114]: [(1, 2.0), (3, 4.0), (4, 324.23)]

从这个元组列表中获取值。其实这也是一个迭代。

In [115]: values=[v for k,v in items]
In [116]: values
Out[116]: [2.0, 4.0, 324.23]

填写data 栏。为了更加安全,我应该使用values[:data.shape[0](以防data 对于这本字典来说不够大)。

In [117]: data[:len(values),0]=values

In [118]: data
Out[118]: 
array([[   2.  ,    0.  ],
       [   4.  ,    0.  ],
       [ 324.23,    0.  ],
       [   0.  ,    0.  ],
       [   0.  ,    0.  ]])

但如果所有字典的大小相同,并且dataarray 是正确的大小,则所有这些交叉检查都可以省略。

【讨论】:

  • 你的最后一个块应该嵌套在 for 循环中,因为我有多个 dicts。我说的对吗?
  • 是的,它的目的是对以前的一部分进行修改。
  • 几个问题:1)dataarray太小为什么会出问题? 2) 你所说的current_dict 应该是adict,对吗? 3) dataarray 的问题是指IndexError: index 2 is out of bounds for axis 1 with size 2 或类似的错误吗?谢谢!并带回超音速队!
  • 很抱歉变量名的改变。当我使用enumerate 时,它会遍历字典中的所有items。您的迭代器循环遍历数组的所有行。无论哪种方式,您都需要确保尺寸匹配并且正确处理任何不匹配。
【解决方案2】:

假设您在名为dicts 的列表中有您的字典,并且您从itertools 导入了zip_longestizip_longest(取决于python 版本)。您可以使用 1 班轮做到这一点:

[ tuple('dict{}'.format(i+1) for i in range(len(dicts))) ] + list( zip_longest(*([ v for k,v in sorted(d.items())] for d in dicts)) )

【讨论】:

  • 但它的代码非常密集,因此您可能需要将其拆分以提高可读性
  • 我对这个密度没问题。我唯一的问题:由于我的输出是list,其中第一个tuple 包含我的dicts 的名称,后来的元组包含各自的值,我如何将它打印到csv 文件中? for 循环应该是什么样子?谢谢!
  • 使用CSV 模块(例如csvwriter.writerows()
  • csv 写一个列表值得自己的问题。查找savetxt
  • 短语“one liner”的意思是表示一种简洁、富有表现力的做事方式。这就是在一行中做某事的全部意义所在。这里的问题是你不够简洁。您进一步加重了必须解释匿名列表和字典的维护程序员的负担。有时代码越多越好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多