很抱歉,这个问题是否已经得到回答(我找不到任何相关的信息),但是如何在不使用循环或对值进行硬编码的情况下初始化3维数组?
我想创建一个3维的。形状为(x,y,2)的数组,并对其进行初始化,以使第三轴中的值表示前两个轴的索引。例如,[[[0,0],[0,1],[0,2]],[[1,0],[1,1],[1,2]]]。我不想使用循环来做到这一点(尽管这样做非常简单),因为实际尺寸会很大(对于图像处理应用程序而言),并且我想避免使用循环。>
这是显而易见的方式:
arr = np.empty((600,800,2))
for row in range(600):
for col in range(800):
arr[row,col] = [row,col]
是否有一种更有效的,类似numpy的方法?
答案 0 :(得分:2)
Numpy具有np.indices((行,列))
np.indices((800, 600)).shape
# (2, 800, 600)
res= np.indices((800, 600)).swapaxes(0,2).swapaxes(0,1)
res.shape
# (800, 600, 2)
%timeit np.indices((800, 600)).swapaxes(0,2).swapaxes(0,1)
# 6.77 ms ± 41.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit try3(800, 600)
# 24 ms ± 702 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
或者使用np.moveaxis。我的时间与双交换轴的时间相同。
np.moveaxis( np.indices((800, 600)), 0, 2)
希望这会有所帮助
答案 1 :(得分:1)
您的代码产生(在较小的情况下):
In [208]: arr = np.empty((3,4,2))
...: for row in range(3):
...: for col in range(4):
...: arr[row,col] = [row,col]
...:
In [209]: arr
Out[209]:
array([[[0., 0.],
[0., 1.],
[0., 2.],
[0., 3.]],
[[1., 0.],
[1., 1.],
[1., 2.],
[1., 3.]],
[[2., 0.],
[2., 1.],
[2., 2.],
[2., 3.]]])
In [221]: arr.shape
Out[221]: (3, 4, 2)
mgrid
是制作网格的几种功能之一,它产生:
In [222]: np.mgrid[0:3,0:4]
Out[222]:
array([[[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2]],
[[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]]])
In [223]: _.shape
Out[223]: (2, 3, 4)
我们可以通过转置得到arr
:
In [224]: np.mgrid[0:3,0:4].transpose(1,2,0).shape
Out[224]: (3, 4, 2)
np.meshgrid
产生相似的结果,但作为数组的元组。
还可以使用repeat
和tile
上的np.arange(3)
和np.arange(4)
的混合。
np.reshape(list(np.ndindex(3,4)),(3,4,2))
np.reshape(list(itertools.product(range(3),range(4))),(3,4,2))
也可以使用,尽管它的速度可能与您的代码相似。 `
答案 2 :(得分:0)
当涉及到numpy时,请尽可能避免迭代。这里一种可能的方法是,您可以使用arange
来构造一个一维数组,其中包含所有您需要预先准备的数字,然后使用一些numpy操纵来获得所需的输出。
import numpy as np
x = 600
y = 800
def try1(x, y):
arr = np.empty((x,y,2))
for row in range(x):
for col in range(y):
arr[row,col] = [row,col]
return arr
def try2(x, y):
temp = np.arange(x * y)
outer = temp // y
inner = temp % y
out = np.dstack((outer, inner)).reshape(x, y, 2)
return out
%timeit try1(x, y)
#489 ms ± 2.22 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit try2(x, y)
#10.6 ms ± 98.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
编辑:
我还添加了hpaulj的mgrid答案,这显然更好:
def try3(x, y):
return np.mgrid[0:x,0:y].transpose(1,2,0)
%timeit try3(x, y)
#8.39 ms ± 43.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
答案 3 :(得分:0)
我想我可以使用以下代码实现您想要的:
import numpy as np
arr = np.empty((600,800,2))
first_indices = np.repeat(np.arange(600).reshape(600, 1), 800, axis=1)
arr[:,:,0] = first_indices
second_indices = np.repeat(np.arange(800).reshape(800,1), 600, axis=1).T
arr[:,:,1] = second_indices
print(arr)
这有点简洁,但是np.arange创建索引0-599和0-799。然后必须将它们从形状(600,)和(800,)重塑为形状(600,1)和(800,1)。然后,我使用numpy.repeat分别复制数组800和600次,以实现形状为(600,800)和(800,600)的2D数组。最后,我将后者换位以实现两个2D形状的数组(600、800),第一个数组具有行的索引,第二个数组具有列的索引。
arr = np.empty((600,800,2))
# x_indices = [0 1 2 ... 597 598 599]
x_indices = np.arange(600)
# x_indices from shape (600,) to (600,1)
x_indices = x_indices.reshape(600,1)
# duplicate x_indices 800 times:
# <-----------800------------->
# x_indices = [[ 0 0 0 ... 0 0 0]] ^
# [[ 1 1 1 ... 1 1 1]] |
# [[ 2 2 2 ... 2 2 2]] |
# ... 600
# [[597 597 597 ... 597 597 597]] |
# [[598 598 598 ... 598 598 598]] |
# [[599 599 599 ... 599 599 599]] V
x_indices = np.repeat(x_indices, 800, axis=1)
# y_indices = [0 1 2 ... 797 798 799]
y_indices = np.arange(800)
# y_indices from shape (800,) to (800,1)
y_indices = y_indices.reshape(800,1)
# duplicate y_indices 600 times:
# <-----------600------------->
# y_indices = [[ 0 0 0 ... 0 0 0]] ^
# [[ 1 1 1 ... 1 1 1]] |
# [[ 2 2 2 ... 2 2 2]] |
# ... 800
# [[797 797 797 ... 797 797 797]] |
# [[798 798 798 ... 798 798 798]] |
# [[799 799 799 ... 799 799 799]] V
y_indices = np.repeat(y_indices, 600, axis=1)
# transpose y_indices
# <---------800---------->
# y_indices = [[0 1 2 ... 797 798 799]] ^
# [[0 1 2 ... 797 798 799]] |
# [[0 1 2 ... 797 798 799]] |
# ... 600
# [[0 1 2 ... 797 798 799]] |
# [[0 1 2 ... 797 798 799]] |
# [[0 1 2 ... 797 798 799]] V
y_indices = y_indices.T
arr[:,:,0] = x_indices
arr[:,:,1] = y_indices