向量化numpy/scipy中的for循环? [英] vectorizing a for loop in numpy/scipy?

查看:87
本文介绍了向量化numpy/scipy中的for循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图向量化我在类方法中包含的for循环. for循环具有以下形式:迭代一堆点,并取决于某个变量(以下称为"self.condition_met")是否为真,在该点上调用一对函数,并将结果添加到列表中.这里的每个点都是列表向量中的一个元素,即看起来像array([[1,2,3],[4,5,6],...])的数据结构.这是有问题的功能:

I'm trying to vectorize a for loop that I have inside of a class method. The for loop has the following form: it iterates through a bunch of points and depending on whether a certain variable (called "self.condition_met" below) is true, calls a pair of functions on the point, and adds the result to a list. Each point here is an element in a vector of lists, i.e. a data structure that looks like array([[1,2,3], [4,5,6], ...]). Here is the problematic function:

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之前设置的,因此似乎没有必要每次都对其进行检查,但是我不确定如何更好地编写它.由于这里没有破坏性操作,看来我可以将整个事情重写为矢量化操作-可能吗?任何想法如何做到这一点?

self.condition_met is set before my_inefficient_method is called, so it seems unnecessary to check it each time, but I am not sure how to better write this. Since there are no destructive operations here it is seems like I could rewrite this entire thing as a vectorized operation -- is that possible? any ideas how to do this?

推荐答案

这只需要在NumPy中使用几行代码(其余只是创建数据集,几个函数和设置).

This only takes a couple lines of code in NumPy (the rest is just creating a data set, a couple of functions, and set-up).

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]]

从您的描述中,我抽象出了以下流程:

From your description i abstracted this flow:

  • 检查条件(布尔值)是否 没错
  • 在这些数据上调用配对函数 满足以下条件的点(行) 条件
  • 追加每组通话的结果 到列表(下面是"res")
  • check for condition (boolean) 'if True'
  • calls pair functions on those data points (rows) that satisfy the condition
  • appends result from each set of calls to a list ('res' below)

这篇关于向量化numpy/scipy中的for循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆