【问题标题】:vectorizing a for loop in numpy/scipy?在numpy/scipy中矢量化for循环?
【发布时间】:2011-02-09 20:06:19
【问题描述】:

我正在尝试对类方法内部的 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'

self.condition_met 是在调用 my_inefficient_method 之前设置的,所以似乎没有必要每次都检查它,但我不知道如何更好地写这个。由于这里没有破坏性操作,似乎我可以将整个事情重写为矢量化操作——这可能吗?任何想法如何做到这一点?

【问题讨论】:

    标签: python optimization numpy scipy vectorization


    【解决方案1】:

    这只需要 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”)

    【讨论】:

      【解决方案2】:

      最好做 mtrw,但如果你不确定矢量化,你可以在my_funcs 上尝试 numpy.vectorize

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

      【讨论】:

      • "提供vectorize函数主要是为了方便,而不是为了性能。实现本质上是一个for循环。"
      【解决方案3】:

      你能重写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'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-06
        • 1970-01-01
        • 2020-05-03
        • 2018-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多