我有一个函数将整数转换为长度为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)]]
答案 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
快,这只是一种便利功能,而不是性能。