使用numpy为一些统计对象创建一个集合字典

时间:2017-08-08 04:20:48

标签: numpy dictionary collections statistics

我想使用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来收集它们。

为此目的,我记录了一种笨拙的方法(假设已确定keyni)为以下代码:

a

毫无疑问,当bimport 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] 很大时,这将非常缓慢。 有没有其他有效的方法来取代上述的? 寻求你的帮助!

2 个答案:

答案 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)

谢谢你的想法。它可以完全解决我的问题。您的核心概念是对a和b进行比较,并将布尔数组作为结果。因此,将数组b的布尔索引用于构建字典要快得多。按照这个想法,我以自己的方式重写你的代码

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)