在多次尝试优化代码后,似乎最后一个资源是尝试使用多个核心运行下面的代码。我不知道如何转换/重构我的代码,以便在使用多个核心时可以运行得更快。如果我能得到指导来实现最终目标,我将不胜感激。最终目标是能够尽可能快地运行数组A和B,其中每个数组包含约700,000个元素。这里是使用小数组的代码。 700k元素数组已被注释掉。
从Matlab中可以看出:Locb包含A中每个值在B中的最低索引。输出数组Locb在A不属于B的地方包含0。
主要问题之一是我需要尽可能高效地执行此操作。测试时,我有两个包含70万个元素的数组。创建生成器并遍历生成器的值似乎无法快速完成任务。
import numpy as np
def ismember(a,b):
for i in a:
index = np.where(b==i)[0]
if index.size == 0:
yield 0
else:
yield index
def f(A, gen_obj):
my_array = np.arange(len(A))
for i in my_array:
my_array[i] = gen_obj.next()
return my_array
#A = np.arange(700000)
#B = np.arange(700000)
A = np.array([3,4,4,3,6])
B = np.array([2,5,2,6,3])
gen_obj = ismember(A,B)
f(A, gen_obj)
print 'done'
# if we print f(A, gen_obj) the output will be: [4 0 0 4 3]
# notice that the output array needs to be kept the same size as array A.
我想做的是模仿一个名为ismember[2]的 MATLAB 函数(格式为:[Lia,Locb]=ismember(A,B)
),我只需要得到Locb
部分。从Matlab中可以看出:Locb包含A中每个值在B中的最低索引。输出数组Locb在A不属于B的地方包含0。
主要问题之一是我需要尽可能高效地执行此操作。测试时,我有两个包含70万个元素的数组。创建生成器并遍历生成器的值似乎无法快速完成任务。
np.where
需要对B
进行线性扫描,这需要O(len(B))
个操作。 然后使用一个外循环,需要O(len(A))
个操作,使得您的原始算法大约需要O(len(A)*len(B))
个操作。 生成Bind
需要len(B)
个操作。 字典实现为hash表,具有常数O(1)
的查找,因此扫描A是O(len(A))
;总体复杂度为O(len(A)+len(B))
。 - sfstewman{ B[i] : i for i in xrange(len(B)-1,-1,-1) }
。或者使用反向迭代器:{ elt : len(B)-i-1) for (i,elt) in enumerate(reversed(B)) }
。两种方法都不太美观(或简单)。第一种假设B是可索引的,第二种假设B是可逆的。它们还假设随机索引/反向迭代是廉价的。如果B是非常大的链表,则性能将非常糟糕。是否有一种使用推导式仅假定迭代以检索第一个索引的方法? - sfstewman