我似乎很难理解数组索引。
给出了什么:
我有一个像这样的3d数组:
a_3d = np.zeros((3,3,3))
2d索引数组:
a_2d_index = np.array([[0,0,1], [0,0,0], [0,1,1]]).astype('bool')
将值放入x,y位置的3d数组中:
a_1d_fill = np.array([10,20,30])
现在,我想使用a_2d_index查找a_3d中的位置,并将a_1d_fill垂直放置在此x,y位置......
最终结果应如下所示:
a_3d := [[[0,0, 10],
[0,0, 0],
[0,10,10]],
[[0,0, 20],
[0,0, 0],
[0,20,20]],
[[0,0, 30],
[0,0, 0],
[0,30,30]]]
这将用于非常大的阵列,因此内存效率和速度至关重要......(少量复制,最好是就地修改)
答案 0 :(得分:4)
In [26]: a_3d = np.zeros((3,3,3), dtype=int)
In [27]: a_2d_index = np.array([[0,0,1], [0,0,0], [0,1,1]]).astype('bool')
In [28]: a_1d_fill = np.array([10,20,30])
In [29]: a_3d[:,a_2d_index] = a_1d_fill[:,np.newaxis]
In [30]: a_3d
Out[30]:
array([[[ 0, 0, 10],
[ 0, 0, 0],
[ 0, 10, 10]],
[[ 0, 0, 20],
[ 0, 0, 0],
[ 0, 20, 20]],
[[ 0, 0, 30],
[ 0, 0, 0],
[ 0, 30, 30]]])
答案 1 :(得分:3)
也许一点点解释和直觉可能会帮助未来的读者更好地理解切片。 我(无耻地)使用Stuart Berg's solution来解释用户以获得切片的直观感觉。
阵列&面具定义:
In [57]: a_3d # array with unique numbers for better understanding.
Out[57]:
array([[[13, 14, 15],
[23, 24, 25],
[33, 34, 35]],
[[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]],
[[ 0, 1, 2],
[30, 31, 32],
[40, 41, 42]]], dtype=uint8)
将上述3D数组理解为三个3x3
数组,其中最顶层的数组具有索引0
,中间一个数据库具有索引1
,而下一个数组具有索引{{1} }}
布尔掩码:
2
现在,让我们使用布尔掩码In [58]: a_2d_index
Out[58]:
array([[False, False, True],
[False, False, False],
[False, True, True]], dtype=bool)
a_3d
进行切片
a_2d_index
好的,现在我们得到了上述结果。为什么以及如何?所以,想象一下:我们采用boolean-mask数组,只在每个切片上叠加数组In [68]: a_3d[:, a_2d_index] # : means apply the mask to all the slices(here 3)
Out[68]:
array([[15, 34, 35],
[ 5, 10, 11],
[ 2, 41, 42]], dtype=uint8)
。
现在,无论掩码中的布尔值为a_3d
,数组True
中的对应元素都会(发光?)并对结果数组有贡献。当我们将掩码放在每个切片上时,每个切片都会发生这种情况(因为我们已使用a_3d
,我们对数组:
中的所有切片执行此操作。)
所以,切片完成了!现在,我们要分配新值(掩码具有布尔值a_3d
)。
分配新值:
True
这是我们拥有的1D阵列。但是,掩模是2D阵列。因此,我们使用In [69]: a_1d_fill
Out[69]: array([10, 20, 30])
np.newaxis
现在,此赋值将值In [70]: a_2d_fill = a_1d_fill[:, np.newaxis]
In [71]: a_2d_fill
Out[71]:
array([[10],
[20],
[30]])
In [73]: a_3d[:, a_2d_index] = a_2d_fill
复制到布尔掩码具有10
值的第一个切片中的索引,然后将值True
复制到布尔值的第二个切片中的索引mask具有值20
,最后将值True
复制到第三个切片中的索引,其中布尔掩码的值为30
。
最终结果如下:
True
唷!那太长了。因此,简而言之,结果数组应具有值In [74]: a_3d
Out[74]:
array([[[13, 14, 10],
[23, 24, 25],
[33, 10, 10]],
[[ 3, 4, 20],
[ 6, 7, 8],
[ 9, 20, 20]],
[[ 0, 1, 30],
[30, 31, 32],
[40, 30, 30]]], dtype=uint8)
,10
和&第一个,第二个和第三个切片中的20
(布尔掩码的值分别为30
)。
P.S。:Slicing提供原始数组的视图或引用。因此,当我们使用切片更改值时,这将影响原始数组。因此,这是一个就地修改。