在numpy/scipy中向量化for循环?
我正在尝试把一个类方法中的for循环进行向量化。这个for循环的形式是这样的:它会遍历一堆点,根据一个叫“self.condition_met”的变量是否为真,来对每个点调用一对函数,然后把结果添加到一个列表中。这里的每个点都是一个列表中的元素,也就是一种数据结构,看起来像这样:array([[1,2,3], [4,5,6], ...])。下面是有问题的函数:
def myClass:
def my_inefficient_method(self):
final_vector = []
# Assume 'my_vector' and 'my_other_vector' are defined numpy arrays
for point in all_points:
if not self.condition_met:
a = self.my_func1(point, my_vector)
b = self.my_func2(point, my_other_vector)
else:
a = self.my_func3(point, my_vector)
b = self.my_func4(point, my_other_vector)
c = a + b
final_vector.append(c)
# Choose random element from resulting vector 'final_vector'
在调用my_inefficient_method之前,self.condition_met已经被设置好了,所以每次检查它似乎没必要,但我不太确定该怎么更好地写这个。因为这里没有破坏性操作,所以我觉得可以把整个过程重写成一个向量化的操作——这可能吗?有没有什么想法可以做到这一点?
3 个回答
0
最好还是按照mtrw的建议来做,不过如果你对向量化不太确定,可以试试在my_func
上使用numpy.vectorize。
http://docs.scipy.org/doc/numpy/reference/generated/numpy.vectorize.html
2
你能把 my_funcx
改写成向量化的形式吗?如果可以的话,你可以这样做:
def myClass:
def my_efficient_method(self):
# Assume 'all_points', 'my_vector' and 'my_other_vector' are defined numpy arrays
if not self.condition_met:
a = self.my_func1(all_points, my_vector)
b = self.my_func2(all_points, my_other_vector)
else:
a = self.my_func3(all_points, my_vector)
b = self.my_func4(all_points, my_other_vector)
final_vector = a + b
# Choose random element from resulting vector 'final_vector'
3
在NumPy中,这只需要几行代码(其他部分只是创建数据集、几个函数和一些设置)。
import numpy as NP
# create two functions
fnx1 = lambda x : x**2
fnx2 = lambda x : NP.sum(fnx1(x))
# create some data
M = NP.random.randint(10, 99, 40).reshape(8, 5)
# creates index array based on condition satisfaction
# (is the sum (of that row/data point) even or odd)
ndx = NP.where( NP.sum(M, 0) % 2 == 0 )
# only those data points that satisfy the condition (are even)
# are passed to one function then another and the result off applying both
# functions to each data point is stored in an array
res = NP.apply_along_axis( fnx2, 1, M[ndx,] )
print(res)
# returns: [[11609 15309 15742 12406 4781]]
根据你的描述,我总结了这个流程:
- 检查条件(布尔值)‘如果为真’
- 对满足条件的数据点(行)调用配对函数
- 将每组调用的结果添加到一个列表中(下面的'res')