Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:lambda函数数组的矢量化求值_Python_Arrays_Numpy_Lambda_Vectorization - Fatal编程技术网

Python: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的阵列似乎不切实际,但是对于任意大小的阵列,我假设这将产生性能提升,因为所有的低级别优化 那么,有人知道如何编写

您将如何向量化lambda函数数组的求值

这里有一个例子来理解我所说的。(即使我使用的是
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