Numpy - 将numpy函数转换为生成器

时间:2016-11-30 19:47:43

标签: python performance numpy generator

我有一个numpy函数,它将x,y坐标的2D数组转换为前一个坐标之间每个坐标距离的平面数组。 (见Numpy - transform 2D array of x,y coordinates into flat array of distance between coordinates

input = [[-8081441,5685214], [-8081446,5685216], [-8081442,5685219], [-8081440,5685211], [-8081441,5685214]]
output = [-8081441, 5685214, 5, -2, -4, -3, -2, 8, 1, -3]

感谢Divakar's answer,我有两个numpy函数正在做我想要的事情

arr = np.asarray(input).astype(int)
np.hstack((arr[0], (-np.diff(arr, axis=0)).ravel()))

采用切片来复制分化的另一种方法 -

arr = np.asarray(input).astype(int)
np.hstack((arr[0], (arr[:-1,:] - arr[1:,:]).ravel()))

我的问题是,有没有办法将其中一个numpy函数转换为生成器以提高性能?是否可以在生成器中使用numpy?

1 个答案:

答案 0 :(得分:2)

Python生成器是列表的衍生产品。

In [207]: [i*2 for i in range(3)]
Out[207]: [0, 2, 4]
In [208]: (i*2 for i in range(3))
Out[208]: <generator object <genexpr> at 0xb6a1ffbc>
In [209]: list(_)
Out[209]: [0, 2, 4]

您可以将其视为懒惰列表。在迭代它之前,它实际上不会评估元素。在Py3 range中是一个生成器(Py2中的xrange)。 In[208]行设置生成器,但不评估任何内容。所以它很快。但是在[209]中迭代它的时间和[207]中的原始时间一样长。 (好吧可能会有细微差别。)

因此,生成器允许您使用列表在块中进行思考,而无需创建所有中间列表。它更像是一种代码组织工具,而不是一种性能工具。

使用numpy数组时,我无法想到任何等价物。

arr=np.array(input)  # creates fixed size array from input list
-np.diff(arr, axis=0)   # create another array

这会创建许多中间数组,甚至是列表,并最终返回一个数组(并丢弃中间体):

np.hstack((arr[0],(-np.diff(arr, axis=0)).ravel()))

该表达式中有许多简单的构建块。 Numpy的速度来自于在快速编译的代码中执行这些步骤。为了获得更好的速度,你必须在C或Cython中重写问题。在该代码中,您可以迭代,并在每个步骤执行复杂的操作。

可以想象numpy可以执行某种懒惰的评估,但这需要主要的低级编码。而且无法保证它会带来性能提升。

我查看了中间缓冲区的问题,以及add.at是否提高了性能(它没有):https://stackoverflow.com/a/40688879/901925

相关问题