我想使用numpy为一些统计对象创建一个收集字典,简化状态如下。
分别有一个标量数组
<data name="ToolTip.Content" xml:space="preserve">
<value>新画笔</value>
<comment>提示用户这是一个新画笔按钮</comment>
</data>
和2D数组一样
a = np.array([n1,n2,n3...])
对于b = np.array([[q1_1,q1_2],[q2_1,q2_2],[q3_1,q3_2]...])
中的每个元素ni
,我想在a
中挑选出包含qi([qi_1,qi_2])
的所有元素ni
并制作{{1}使用b
作为dict
来收集它们。
为此目的,我记录了一种笨拙的方法(假设已确定key
和ni
)为以下代码:
a
毫无疑问,当b
和import numpy as np
a = np.array([i+1 for i in range(100)])
b = np.array([[2*i+1,2*(i+1)] for i in range(50)])
dict = {}
for i in a: dict[i] = [j for j in b if i in j]
很大时,这将非常缓慢。
有没有其他有效的方法来取代上述的?
寻求你的帮助!
答案 0 :(得分:0)
Numpy数组允许元素比较:
equal = b[:,:,np.newaxis]==a #np.newaxis to broadcast
# if one of the two is equal, we will include this element
index = np.logical_or(equal[:,0], equal[:,1])
# indexing by a boolean array to get the result
dictionary = {i: b[index[:,i]] for i in range(len(a))}
最后一句话:你确定要使用字典吗?通过这种方式你会失去很多优点
编辑,回答你的评论: 使用a和b这个大,相等将具有10 ^ 10的大小,这使得8 * 10 ^ 10个字节,大约是72G。这就是为什么你得到这个错误的原因。 你应该问的主要问题是:我真的需要这个大阵列吗?如果是,你确定,这个词典也不会变大吗?
问题可以通过不计算一次性来解决,但在n
次,n
应该是大约72/16(内存中的比例)。然而,稍微大一点可能会加快这个过程:
stride = int(len(b)/n)
dictionary = {}
for i in range(n):
#splitting b into several parts
equal = b[n*stride:(n+1)*stride,:,np.newaxis]==a
index = np.logical_or(equal[:,0], equal[:,1])
dictionary.update( {i: b[index[:,i]] for i in range(len(a))})
答案 1 :(得分:0)
dict = {}
for item in a:
index_left, index_right = (b[:,0]==item), (b[:,1]==item)
index = np.logical_or(index_left, index_right)
dict[item] = dict[index]
这些代码仍然不比你的快,但可以避免“记忆错误”。即使在大的a和b中(例如a = 100000和b = 200000)