Numpy从x * y数组向量化为x * y * 3

时间:2017-09-16 15:48:20

标签: python arrays numpy

我有一个函数将整数转换为长度为3的元组,到目前为止我一直在做嵌套for循环和缓存,但它仍然很慢。函数预先计算值并将它们缓存在列表中,然后使用__getitem__进行一些数学计算以确定要返回的值。然后用不同的数字调用数百万次。

我最近开始使用numpy,我想尽可能加快这个过程。我做的初始优化(划分整个numpy数组以匹配缓存长度,因此可以绕过__getitem__)加速一个例子从15到3秒,我想尽可能尝试vectorize。

唯一的问题是我无法弄清楚如何使用vectorize将w*h数组转换为w*h*3数组,并想知道是否有人知道如何?我考虑过添加一个额外的维度,但它似乎更像是一个重塑类型的东西。

以下是一些示例代码:

>>> height, width = 2, 5

>>> array = numpy.arange(width * height).reshape(height, width)
[[0 1 2 3 4]
 [5 6 7 8 9]]

>>> test_list = [(0, i, 0) for i in range(width * height)]
>>> numpy.vectorize(test_list.__getitem__)(array)
(array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]]), array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]]), array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]]))

#expected = [[(0, 0, 0) (0, 1, 0) (0, 2, 0) (0, 3, 0) (0, 4, 0)]
#            [(0, 5, 0) (0, 6, 0) (0, 7, 0) (0, 8, 0) (0, 9, 0)]]

1 个答案:

答案 0 :(得分:1)

在这种情况下你可以简单地使用作业:

>>> import numpy as np
>>> height, width = 2, 5
>>> array = np.arange(width * height).reshape(height, width)
>>> res = np.zeros((height, width, 3), dtype=array.dtype)
>>> res[:, :, 1].flat = array.ravel()
>>> res
array([[[0, 0, 0],
        [0, 1, 0],
        [0, 2, 0],
        [0, 3, 0],
        [0, 4, 0]],

       [[0, 5, 0],
        [0, 6, 0],
        [0, 7, 0],
        [0, 8, 0],
        [0, 9, 0]]])

如果你想要元组,你可能最好使用普通的for循环和普通列表:

>>> lst = array.tolist()
>>> res = [[(0, item, 0) for item in sublst] for sublst in lst]
>>> res 
[[(0, 0, 0), (0, 1, 0), (0, 2, 0), (0, 3, 0), (0, 4, 0)],
 [(0, 5, 0), (0, 6, 0), (0, 7, 0), (0, 8, 0), (0, 9, 0)]]

这两种方法(可能)比np.vectorize快,这只是一种便利功能,而不是性能。