我有一组numpy数组。其中之一是“键”列表,我想将数组重新排列成键在该键上的数组的字典。我当前的代码是:
for key, val1, val2 in itertools.izip(keys, vals1, vals2):
dict1[key].append(val1)
dict2[key].append(val2)
这很慢,因为涉及的数组长达数百万个条目,而且这种情况发生了很多次。是否可以矢量化形式重写它?可能的密钥集是事先已知的,大约有10个不同的密钥。
编辑:如果有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))。实际上,除非n非常大,否则argsort会非常快。在argsort明显变慢之前,您可能会用这种方法遇到内存问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句