填写 numpy ndarray 的最佳方法?
best way to fill in a numpy ndarray?
我使用以下代码生成带有渐变的图像。我逐个元素访问数组。有更好的方法吗?谢谢
import cv2
import numpy as np
x = np.ndarray((256,256,3), dtype=np.uint8)
for i in xrange(256):
for j in xrange(256):
for k in xrange(3):
x[i, j, k] = i
cv2.imwrite('SYxmp_out.jpg', x)
对于 i、j 的所有值,您的目标似乎是用 i
填充 x[i, j, k]
和 k.
你可以构造这样的数组:
x = np.repeat(np.arange(256, dtype=np.uint8), (256*3)).reshape(256, 256, 3)
然后我们得到一个如下所示的数组:
>>> np.repeat(np.arange(256, dtype=np.uint8), (256*3)).reshape(256, 256, 3)
array([[[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0],
...,
[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0]],
[[ 1, 1, 1],
[ 1, 1, 1],
[ 1, 1, 1],
...,
[ 1, 1, 1],
[ 1, 1, 1],
[ 1, 1, 1]],
[[ 2, 2, 2],
[ 2, 2, 2],
[ 2, 2, 2],
...,
[ 2, 2, 2],
[ 2, 2, 2],
[ 2, 2, 2]],
...,
[[253, 253, 253],
[253, 253, 253],
[253, 253, 253],
...,
[253, 253, 253],
[253, 253, 253],
[253, 253, 253]],
[[254, 254, 254],
[254, 254, 254],
[254, 254, 254],
...,
[254, 254, 254],
[254, 254, 254],
[254, 254, 254]],
[[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
...,
[255, 255, 255],
[255, 255, 255],
[255, 255, 255]]], dtype=uint8)
对于第二个轴,我们可以使用np.tile
:
>>> np.tile(np.repeat(np.arange(256, dtype=np.uint8), 3), 256).reshape(256, 256, 3)
array([[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]],
[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]],
[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]],
...,
[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]],
[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]],
[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]]], dtype=uint8)
尽管如果事情更复杂,广播可能是更好的主意。例如,对于第一个维度,我们可以使用:
x = np.zeros((256, 256, 3))
x[:] = np.arange(256)[:,None,None]
而对于第二个,我们可以使用:
x = np.zeros((256, 256, 3))
x[:] = np.arange(256)[None,:,None]
或不提及 256 两次:
而对于第二个,我们可以使用:
x = np.zeros((256, 256, 3))
x[:] = np.arange(x.shape[0])[:,None,None]
# second dimension
x = np.zeros((256, 256, 3))
x[:] = np.arange(x.shape[1])[None,:,None]
基准:
如果我 运行 问题中的代码 (f
)、答案中的代码 (g
) 和广播版本 (h
) i7-7500U CPU @ 2.70GHz 一百次,我获得以下基准:
>>> timeit(f, number=100)
3.1465475099976175
>>> timeit(g, number=100)
0.05008594098035246
>>> timeit(h, number=100)
0.03603723298874684
所以这应该意味着 g
比 f
大约提速 62 倍,h
比 f
提速大约 87 倍。
我使用以下代码生成带有渐变的图像。我逐个元素访问数组。有更好的方法吗?谢谢
import cv2
import numpy as np
x = np.ndarray((256,256,3), dtype=np.uint8)
for i in xrange(256):
for j in xrange(256):
for k in xrange(3):
x[i, j, k] = i
cv2.imwrite('SYxmp_out.jpg', x)
对于 i、j 的所有值,您的目标似乎是用 i
填充 x[i, j, k]
和 k.
你可以构造这样的数组:
x = np.repeat(np.arange(256, dtype=np.uint8), (256*3)).reshape(256, 256, 3)
然后我们得到一个如下所示的数组:
>>> np.repeat(np.arange(256, dtype=np.uint8), (256*3)).reshape(256, 256, 3)
array([[[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0],
...,
[ 0, 0, 0],
[ 0, 0, 0],
[ 0, 0, 0]],
[[ 1, 1, 1],
[ 1, 1, 1],
[ 1, 1, 1],
...,
[ 1, 1, 1],
[ 1, 1, 1],
[ 1, 1, 1]],
[[ 2, 2, 2],
[ 2, 2, 2],
[ 2, 2, 2],
...,
[ 2, 2, 2],
[ 2, 2, 2],
[ 2, 2, 2]],
...,
[[253, 253, 253],
[253, 253, 253],
[253, 253, 253],
...,
[253, 253, 253],
[253, 253, 253],
[253, 253, 253]],
[[254, 254, 254],
[254, 254, 254],
[254, 254, 254],
...,
[254, 254, 254],
[254, 254, 254],
[254, 254, 254]],
[[255, 255, 255],
[255, 255, 255],
[255, 255, 255],
...,
[255, 255, 255],
[255, 255, 255],
[255, 255, 255]]], dtype=uint8)
对于第二个轴,我们可以使用np.tile
:
>>> np.tile(np.repeat(np.arange(256, dtype=np.uint8), 3), 256).reshape(256, 256, 3)
array([[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]],
[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]],
[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]],
...,
[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]],
[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]],
[[ 0, 0, 0],
[ 1, 1, 1],
[ 2, 2, 2],
...,
[253, 253, 253],
[254, 254, 254],
[255, 255, 255]]], dtype=uint8)
尽管如果事情更复杂,广播可能是更好的主意。例如,对于第一个维度,我们可以使用:
x = np.zeros((256, 256, 3))
x[:] = np.arange(256)[:,None,None]
而对于第二个,我们可以使用:
x = np.zeros((256, 256, 3))
x[:] = np.arange(256)[None,:,None]
或不提及 256 两次:
而对于第二个,我们可以使用:
x = np.zeros((256, 256, 3))
x[:] = np.arange(x.shape[0])[:,None,None]
# second dimension
x = np.zeros((256, 256, 3))
x[:] = np.arange(x.shape[1])[None,:,None]
基准:
如果我 运行 问题中的代码 (f
)、答案中的代码 (g
) 和广播版本 (h
) i7-7500U CPU @ 2.70GHz 一百次,我获得以下基准:
>>> timeit(f, number=100)
3.1465475099976175
>>> timeit(g, number=100)
0.05008594098035246
>>> timeit(h, number=100)
0.03603723298874684
所以这应该意味着 g
比 f
大约提速 62 倍,h
比 f
提速大约 87 倍。