2010-04-19 83 views
4

我試圖向量化一個for循環,我有一個類的方法裏面。 for循環具有以下形式:它通過一串點的迭代,並且根據一定的變量(稱爲「self.condition_met」下方)是否爲真,呼籲點一對函數,並將結果添加到列表。這裏的每個點是在列表中的一個向量的元素,即一個數據結構,它看起來像陣列([[1,2,3],[4,5,6],...])。這是有問題的功能:在numpy/scipy中矢量化循環?

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' 

self.condition_met設置之前my_inefficient_method被調用,因此它似乎沒有必要每次都檢查了,但我不知道如何更好地寫。由於這裏沒有破壞性操作,所以似乎我可以將整個事件重寫爲矢量化操作 - 這可能嗎?任何想法如何做到這一點?

回答

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' 
2

numpy.vectorize這隻需要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'下面)