Python:lambda函数数组的矢量化求值
您将如何向量化lambda函数数组的求值 这里有一个例子来理解我所说的。(即使我使用的是Python:lambda函数数组的矢量化求值,python,arrays,numpy,lambda,vectorization,Python,Arrays,Numpy,Lambda,Vectorization,您将如何向量化lambda函数数组的求值 这里有一个例子来理解我所说的。(即使我使用的是numpy数组,我也不局限于只使用numpy) 假设我有以下numpy数组 array1 = np.array(["hello", 9]) array2 = np.array([lambda s: s == "hello", lambda num: num < 10]) 当然,这对于大小为2的阵列似乎不切实际,但是对于任意大小的阵列,我假设这将产生性能提升,因为所有的低级别优化 那么,有人知道如何编写
numpy
数组,我也不局限于只使用numpy
)
假设我有以下numpy
数组
array1 = np.array(["hello", 9])
array2 = np.array([lambda s: s == "hello", lambda num: num < 10])
当然,这对于大小为2的阵列似乎不切实际,但是对于任意大小的阵列,我假设这将产生性能提升,因为所有的低级别优化
那么,有人知道如何编写这种奇怪的python代码吗?当然,简单的答案是,使用numpy(或者标准python)很难做到这一点。据我所知,Numpy实际上并没有对大多数操作本身进行矢量化:它使用BLAS/ATLAS/等库,在某些情况下可以这样做。即使它这样做了,它也会在特定情况下在C中这样做:它当然不能矢量化Python函数的执行 如果您想在这方面涉及多处理,这是可能的,但这取决于您的情况。您的单个函数应用程序是否耗时,使它们能够逐个发送,或者您是否需要大量的快速函数执行,在这种情况下,您可能希望将它们批量发送到每个进程
一般来说,由于可能被认为是糟糕的基本设计(例如,全局解释器锁),标准Python很难实现您希望的轻量级并行化。还有一些更重的方法,如多处理模块或Ipython.parallel,但这些方法需要一些工作才能使用。当然,简单的答案是,使用numpy(或者标准Python)很难做到这一点。据我所知,Numpy实际上并没有对大多数操作本身进行矢量化:它使用BLAS/ATLAS/等库,在某些情况下可以这样做。即使它这样做了,它也会在特定情况下在C中这样做:它当然不能矢量化Python函数的执行 如果您想在这方面涉及多处理,这是可能的,但这取决于您的情况。您的单个函数应用程序是否耗时,使它们能够逐个发送,或者您是否需要大量的快速函数执行,在这种情况下,您可能希望将它们批量发送到每个进程
一般来说,由于可能被认为是糟糕的基本设计(例如,全局解释器锁),标准Python很难实现您希望的轻量级并行化。还有一些更重的方法,如多处理模块或Ipython.parallel,但这些方法需要一些工作才能使用。当然,简单的答案是,使用numpy(或者标准Python)很难做到这一点。据我所知,Numpy实际上并没有对大多数操作本身进行矢量化:它使用BLAS/ATLAS/等库,在某些情况下可以这样做。即使它这样做了,它也会在特定情况下在C中这样做:它当然不能矢量化Python函数的执行 如果您想在这方面涉及多处理,这是可能的,但这取决于您的情况。您的单个函数应用程序是否耗时,使它们能够逐个发送,或者您是否需要大量的快速函数执行,在这种情况下,您可能希望将它们批量发送到每个进程
一般来说,由于可能被认为是糟糕的基本设计(例如,全局解释器锁),标准Python很难实现您希望的轻量级并行化。还有一些更重的方法,如多处理模块或Ipython.parallel,但这些方法需要一些工作才能使用。当然,简单的答案是,使用numpy(或者标准Python)很难做到这一点。据我所知,Numpy实际上并没有对大多数操作本身进行矢量化:它使用BLAS/ATLAS/等库,在某些情况下可以这样做。即使它这样做了,它也会在特定情况下在C中这样做:它当然不能矢量化Python函数的执行 如果您想在这方面涉及多处理,这是可能的,但这取决于您的情况。您的单个函数应用程序是否耗时,使它们能够逐个发送,或者您是否需要大量的快速函数执行,在这种情况下,您可能希望将它们批量发送到每个进程
一般来说,由于可能被认为是糟糕的基本设计(例如,全局解释器锁),标准Python很难实现您希望的轻量级并行化。还有更重的方法,比如多处理模块或Ipython.parallel,但这些都需要一些工作来使用。好了,伙计们,我有一个答案:numpy的 但请阅读编辑的部分。您将发现python实际上为您优化了代码,这实际上违背了在本例中使用numpy数组的目的。(但使用numpy阵列不会降低性能。) 最后一个测试真正表明python列表是尽可能高效的,因此这个向量化过程是不必要的。这就是为什么我没有把这个问题标为“最佳答案” 设置代码:
def factory(i): return lambda num: num==i
array1 = list()
for i in range(10000): array1.append(factory(i))
array1 = np.array(array1)
array2 = np.array(xrange(10000))
def factory(i): return lambda num: str(num)==str(i)
array1 = list()
for i in range(7):
array1.append(factory(i))
array1 = np.array(array1)
array2 = np.array(xrange(7))
“非部门化”版本:
矢量化版本
def evaluate2(func, b): return func(b)
vec_evaluate = np.vectorize(evaluate2)
vec_evaluate(array1, array2)
# 100 loops, best of 3: 2.65 ms per loop
编辑
好的,我只是想粘贴更多使用上述测试获得的基准测试,不同的测试用例除外
我做了第三次编辑,显示了如果您只使用python列表会发生什么。长话短说,你其实不会后悔太多。这个测试用例在最底层
仅涉及整数的测试用例
总之,如果n
很小,则未分区的版本为b
def evaluate2(func, b): return func(b)
vec_evaluate = np.vectorize(evaluate2)
vec_evaluate(array1, array2)
# 100 loops, best of 3: 2.65 ms per loop
%timeit evaluate(array1, array2)
# 10000 loops, best of 3: 35.7 µs per loop
%timeit vec_evaluate(array1, array2)
# 10000 loops, best of 3: 27.6 µs per loop
%timeit evaluate(array1, array2)
100000 loops, best of 3: 9.93 µs per loop
%timeit vec_evaluate(array1, array2)
10000 loops, best of 3: 21.6 µs per loop
def factory(i): return lambda num: str(num)==str(i)
array1 = list()
for i in range(7):
array1.append(factory(i))
array1 = np.array(array1)
array2 = np.array(xrange(7))
%timeit evaluate(array1, array2)
10 loops, best of 3: 36.7 ms per loop
%timeit vec_evaluate(array1, array2)
100 loops, best of 3: 6.57 ms per loop
%timeit evaluate(array1, array2)
10000 loops, best of 3: 28.3 µs per loop
%timeit vec_evaluate(array1, array2)
10000 loops, best of 3: 27.5 µs per loop
def factory(i):
if random() < 0.5:
return lambda num: str(num) == str(i)
return lambda num: num == i
%timeit evaluate(array1, array2)
10 loops, best of 3: 25.7 ms per loop
%timeit vec_evaluate(array1, array2)
100 loops, best of 3: 4.67 ms per loop
%timeit evaluate(array1, array2)
10000 loops, best of 3: 23.1 µs per loop
%timeit vec_evaluate(array1, array2)
10000 loops, best of 3: 23.1 µs per loop
def factory(i):
if random() < 0.5:
return lambda num: str(num) == str(i)
return lambda num: num == i
array1 = list()
for i in range(10000): array1.append(factory(i))
array2 = range(10000)
%timeit evaluate(array1, array2)
100 loops, best of 3: 4.93 ms per loop
%timeit vec_evaluate(array1, array2)
10 loops, best of 3: 19.8 ms per loop