векторизация для цикла в Numpy /Scipy?

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

self.condition_met устанавливается перед вызовом my_inefficient_method, поэтому нет необходимости каждый раз проверять его, но я не уверен, как лучше написать это. Поскольку здесь нет деструктивных операций, похоже, я мог бы переписать всю эту вещь как векторизованную операцию - возможно ли это? есть идеи как это сделать?

4 голоса | спросил user248237dfsf 19 PMpMon, 19 Apr 2010 23:17:19 +040017Monday 2010, 23:17:19

3 ответа


0

Можете ли вы переписать 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'
ответил mtrw 19 PMpMon, 19 Apr 2010 23:35:48 +040035Monday 2010, 23:35:48
0

Это займет всего пару строк кода в 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' ниже)
ответил doug 19 PMpMon, 19 Apr 2010 23:52:09 +040052Monday 2010, 23:52:09
0

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

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

ответил Casey W. Stark 19 PMpMon, 19 Apr 2010 23:45:06 +040045Monday 2010, 23:45:06

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132