我有一个形状为numpy
的3-D a
数组(我们称之为(74, 74, 4563)
),我想从中提取长度为n
的子数组前两个维度中的每个位置。但是,每个子阵列都在不同的位置开始,具体取决于前两个维度中的索引i
& j
。
例如,如果n=1000
,我可能需要a[0, 0, 0:1000]
,还需要a[0, 1, 2:1002]
等...我有一个二维数组(称为ix0
)是一个二维数组,告诉我每个子数组在每个i
/ j
位置的起始位置。最后,我保证不会有任何“溢出” - 也就是说,ix0 + n
中的所有值都小于a
的维度-2长度(因此我们不需要担心要求超出现有范围的指数。
例如......
a = np.arange(74*74*4563).reshape(74, 74, 4563)
ix0 = np.arange(74*74).reshape(74,74)/2 + 50
a[:, :, ix0:ix0+n]
产生
IndexError: failed to coerce slice entry of type numpy.ndarray to integer
有没有办法在不循环遍历所有i
/ j
索引组合或创建大掩码数组的情况下执行此操作?
答案 0 :(得分:3)
以前曾经问过这条线,但是2d。我可能会试着看一下。
但是这里有一个关于2d案例中发生的事情的简单例子
In [1463]: x=np.arange(12).reshape(3,4)
In [1464]: ix0=np.array([0,2,1])
In [1465]: N=2
我们可以迭代x
的每一行,收集所需的N
长度切片,然后将它们连接到列表或数组中。更普遍的问题是改变切片的长度,在这种情况下,它们不能重新组装成数组。
In [1466]: [x[i,ix0[i]:ix0[i]+N] for i in range(3)]
Out[1466]: [array([0, 1]), array([6, 7]), array([ 9, 10])]
然后将该列表包装在np.array
。
另一种方法是首先连接索引:
In [1467]: x[np.arange(3)[:,None], np.array([np.r_[ix0[i]:ix0[i]+N] for i in range(3)])]
Out[1467]:
array([[ 0, 1],
[ 6, 7],
[ 9, 10]])
最后一个索引数组是:
In [1468]: np.array([np.r_[ix0[i]:ix0[i]+N] for i in range(3)])
Out[1468]:
array([[0, 1],
[2, 3],
[1, 2]])
要应用于3d案例,我们有两个选择。一个是重塑为2d,应用其中一个策略,并重新塑造。另一个是概括我为创造这些所采取的行动 - 这不应该太难,但需要进行一些实验。
最后一个数组不应该难以通过广播创建。
In [1469]: ix0[:,None]+np.arange(N)
Out[1469]:
array([[0, 1],
[2, 3],
[1, 2]])
In [1470]: x[np.arange(3)[:,None], ix0[:,None]+np.arange(N)]
Out[1470]:
array([[ 0, 1],
[ 6, 7],
[ 9, 10]])
现在应该更容易概括为3d
In [1487]: X=np.arange(2*3*10).reshape(2,3,10)
In [1488]: ix0=np.arange(2*3).reshape(2,3)
In [1489]: ix0[...,None]+np.arange(N)
Out[1489]:
array([[[0, 1],
[1, 2],
[2, 3]],
[[3, 4],
[4, 5],
[5, 6]]])
In [1490]: I,J,_=np.ix_(range(2),range(3),range(N))
In [1491]: I.shape
Out[1491]: (2, 1, 1)
In [1492]: J.shape
Out[1492]: (1, 3, 1)
In [1493]: X[I, J, ix0[...,None]+np.arange(N)]
Out[1493]:
array([[[ 0, 1],
[11, 12],
[22, 23]],
[[33, 34],
[44, 45],
[55, 56]]])
我应该确保值是正确的,但形状匹配,在这种情况下,这是80%的工作。