2010-04-19 5 views
4

Я пытаюсь векторизовать цикл for, который у меня внутри метода класса. Цикл for имеет следующий вид: он выполняет итерацию через кучу точек и в зависимости от того, истинна ли определенная переменная (называемая «self.condition_met»), вызывает пару функций в точке и добавляет результат в список , Каждая точка здесь представляет собой элемент в векторе списков, то есть структуру данных, которая выглядит как массив ([[1,2,3], [4,5,6], ...]). Вот проблематичной функция:векторизация цикла for в 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' 
0

Это, вероятно, лучше всего делать то, что mtrw, но если вы не уверены, векторизации, вы можете попробовать numpy.vectorize на my_func s

http://docs.scipy.org/doc/numpy/reference/generated/numpy.vectorize.html

+2

«Функция векторизации предоставляется в первую очередь для удобства, а не для производительности. Реализация по существу является циклом for. " – endolith

2

Это занимает всего пару строк кода в 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]] 

Из вашего описания я отведенной этот поток:

  • проверки состояния (булево) 'если True'
  • вызовов пара функций на этих данных точек (строки), которые удовлетворяют условие
  • добавляет результат от каждого набора вызовов к списку ('res' ниже)
Смежные вопросы