python - 快速将带有索引的 numpy 数组转换为以该索引为键的 numpy 数组的字典

标签 python numpy vectorization

我有一组 numpy 数组。其中之一是“键”列表,我想将数组重新排列成以该键为键的数组字典。我当前的代码是:

for key, val1, val2 in itertools.izip(keys, vals1, vals2):
    dict1[key].append(val1)
    dict2[key].append(val2)

这非常慢,因为涉及的数组有数百万个条目长,而且这种情况发生了很多次。是否有可能以矢量化形式重写它?一组可能的 key 是提前知道的,并且有大约 10 个不同的 key 。

编辑:如果有 k 个不同的键并且列表有 n 长,则当前答案为 O(nk)(对每个键迭代一次)和 O(n log n)(先排序).不过,我仍在寻找 O(n) 矢量化解决方案。这是有希望的;毕竟,最简单的非向量化事物(即我已经拥有的事物)是 O(n)。

最佳答案

执行此操作的矢量化方法可能需要您对键进行排序。基本思想是对键和值进行排序以匹配。然后,每当排序键数组中有新键时,您就可以拆分 val 数组。矢量化代码看起来像这样:

import numpy as np

keys = np.random.randint(0, 10, size=20)
vals1 = np.random.random(keys.shape)
vals2 = np.random.random(keys.shape)

order = keys.argsort()
keys_sorted = keys[order]

# Find uniq keys and key changes
diff = np.ones(keys_sorted.shape, dtype=bool)
diff[1:] = keys_sorted[1:] != keys_sorted[:-1]
key_change = diff.nonzero()[0]
uniq_keys = keys_sorted[key_change]

vals1_split = np.split(vals1[order], key_change[1:])
dict1 = dict(zip(uniq_keys, vals1_split))

vals2_split = np.split(vals2[order], key_change[1:])
dict2 = dict(zip(uniq_keys, vals2_split))

由于 argsort 步骤,此方法的复杂度为 O(n * log(n))。实际上,argsort 非常快,除非 n 非常大。在 argsort 变得明显变慢之前,您可能会使用此方法遇到内存问题。

关于python - 快速将带有索引的 numpy 数组转换为以该索引为键的 numpy 数组的字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39301666/

相关文章:

python - 在公差范围内查找 Python 中两个矩阵的交集?

visual-studio - 如何在 Visual Studio 2015(对于 C++)中仅禁用 SIMD 自动矢量化优化?

Python: `.replace(' null'、 '""')` 的替代方案,用嵌套 JSON 中的字符串替换 null 和 None 值

python - 具有多列的日期时间的 Numpy genfromtxt 问题

python - 找到给出超过 65 个素数的最低 collat​​z 序列

python 数组在列表中索引列表

python - numpy 对于相同的代码返回一维数组和二维数组

从同一行中指示的列返回值

python - Kivy 无法导入相机

python - Django 将嵌套模板渲染为 pdf