【问题标题】:slicing a 3d numpy array with index as arrays and reshape将索引为数组的 3d numpy 数组切片并重塑
【发布时间】:2021-11-18 03:42:50
【问题描述】:

我有一个 3d 形状数组 (3, 5, 5)。对于 3 个元素中的每一个,我需要沿第 2 轴和第 3 轴使用不同的索引进行切片

ts = np.arange(25*3).reshape(3,5,5)
print(ts)
newr1 = np.array([1,0,2])
newr2 = np.array([3,2,4])

newc1 = np.array([1,2,0])
newc2 = np.array([3,4,2])

我想要ts[:, newr1:newr2, newc1:newc2] 之类的东西,但这种类型的切片仅适用于标量索引。输出应如下所示。请指教

array([[[ 6,  7,  8],
        [11, 12, 13],
        [16, 17, 18]],

       [[27, 28, 29],
        [32, 33, 34],
        [37, 38, 39]],

       [[60, 61, 62],
        [65, 66, 67],
        [70, 71, 72]]])

【问题讨论】:

  • 没有向量化的索引方法,因为没有保证每个子数组将返回具有相同形状的数据。
  • 必须可视化选择。我认为您需要将其表示为迭代、连接结果或构造索引数组。这不是 basic 索引。

标签: python numpy numpy-ndarray numpy-slicing


【解决方案1】:

好吧,我的好奇心战胜了我。即使您没有提供应有的信息,我也会给出答案。

In [10]: ts = np.arange(25*3).reshape(3,5,5)
    ...: print(ts)
    ...: newr1 = np.array([1,0,2])
    ...: newr2 = np.array([3,2,4])
    ...: 
    ...: newc1 = np.array([1,2,0])
    ...: newc2 = np.array([3,4,2])
    ...: 
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]
  [15 16 17 18 19]
  [20 21 22 23 24]]

 [[25 26 27 28 29]
  [30 31 32 33 34]
  [35 36 37 38 39]
  [40 41 42 43 44]
  [45 46 47 48 49]]

 [[50 51 52 53 54]
  [55 56 57 58 59]
  [60 61 62 63 64]
  [65 66 67 68 69]
  [70 71 72 73 74]]]

我猜你想要的是:

In [11]: for i in range(3):
    ...:     x = ts[i,newr1[i]:newr2[i],newc1[i]:newc2[i]]
    ...:     print(x)
    ...: 
[[ 6  7]
 [11 12]]
[[27 28]
 [32 33]]
[[60 61]
 [65 66]]

好的,这很接近,尽管您没有正确处理切片的端点。

linspace 能够为输入数组生成“切片/数组”:

In [13]: np.linspace(newr1,newr2,3)
Out[13]: 
array([[1., 0., 2.],
       [2., 1., 3.],
       [3., 2., 4.]])

尝试使用这样的矩阵作为索引会出错:

In [14]: I=np.linspace(newr1,newr2,3)
In [15]: J=np.linspace(newc1,newc2,3)
In [16]: ts[np.arange(3)[:,None,None], I[:,:,None], J[:,None,:]]
Traceback (most recent call last):
  File "<ipython-input-16-5bc9e51832b8>", line 1, in <module>
    ts[np.arange(3)[:,None,None], I[:,:,None], J[:,None,:]]
IndexError: arrays used as indices must be of integer (or boolean) type

In [17]: I=np.linspace(newr1,newr2,3).astype(int)
In [18]: J=np.linspace(newc1,newc2,3).astype(int)
In [19]: I
Out[19]: 
array([[1, 0, 2],
       [2, 1, 3],
       [3, 2, 4]])
In [20]: J
Out[20]: 
array([[1, 2, 0],
       [2, 3, 1],
       [3, 4, 2]])

在几次错误之后,我得出了:

In [23]: ts[np.arange(3)[:,None,None], I.T[:,:,None], J.T[:,None,:]]
Out[23]: 
array([[[ 6,  7,  8],
        [11, 12, 13],
        [16, 17, 18]],

       [[27, 28, 29],
        [32, 33, 34],
        [37, 38, 39]],

       [[60, 61, 62],
        [65, 66, 67],
        [70, 71, 72]]])

因此,如果切片大小在“平面”之间保持一致,我们可以使用一组适当的索引数组进行选择。

【讨论】:

    猜你喜欢
    • 2017-09-18
    • 2020-04-22
    • 2018-03-17
    • 2020-12-05
    • 2016-05-22
    • 2016-02-10
    • 2021-03-21
    • 2021-08-06
    • 2017-07-03
    相关资源
    最近更新 更多