是否可以使用2d数组切割3d数组。我假设它可以完成,但需要你必须指定轴吗?
如果我有3个数组,那么:
A = [[1,2,3,4,5],
[1,3,5,7,9],
[5,4,3,2,1]] # shape (3,5)
B1 = [[1],
[2],
[3]] # shape (3, 1)
B2 = [[4],
[3],
[4]] # shape (3,1)
是否可以使用B1和B2切割A,如:
Out = A[B1:B2]
所以它会让我回头:
Out = [[2,3,4,5],
[5, 7],
[2, 1]]
如果切片在Out
中创建了不同长度的数组,那么这不起作用吗?
答案 0 :(得分:4)
Numpy针对具有固定尺寸的均匀数字数组进行了优化,因此它不支持不同的行或列大小。
但是,您可以通过使用数组列表来实现您想要的效果:
Out = [A[i, B1[i]:B2[i]+1] for i in range(len(B1))]
答案 1 :(得分:2)
这是一个到 vectorization
-
n_range = np.arange(A.shape[1])
elems = A[(n_range >= B1) & (n_range <= B2)]
idx = (B2 - B1 + 1).ravel().cumsum()
out = np.split(elems,idx)[:-1]
诀窍是使用broadcasting
创建要为输出选择的元素的掩码。然后,在指定位置拆分这些元素的数组以获得数组列表。
示例输入,输出 -
In [37]: A
Out[37]:
array([[1, 2, 3, 4, 5],
[1, 3, 5, 7, 9],
[5, 4, 3, 2, 1]])
In [38]: B1
Out[38]:
array([[1],
[2],
[3]])
In [39]: B2
Out[39]:
array([[4],
[3],
[4]])
In [40]: out
Out[40]: [array([2, 3, 4, 5]), array([5, 7]), array([2, 1])]
# Please note that the o/p is a list of arrays
答案 2 :(得分:0)
您想要的结果在每一行中具有不同数量的术语 - 这是一个强有力的指标,表明完全矢量化的解决方案是不可能的。对于每一行或每一列,它没有做同样的事情。
其次,n:m
转换为slice(n,m)
。 slice
只接受整数,而不是列表或数组。
显而易见的解决方案是对行进行某种迭代:
In [474]: A = np.array([[1,2,3,4,5],
[1,3,5,7,9],
[5,4,3,2,1]]) # shape (3,5)
In [475]: B1=[1,2,3] # no point in making these 2d
In [476]: B2=[5,4,5] # corrected values
In [477]: [a[b1:b2] for a,b1,b2 in zip(A,B1,B2)]
Out[477]: [array([2, 3, 4, 5]), array([5, 7]), array([2, 1])]
如果A
是嵌套列表
In [479]: [a[b1:b2] for a,b1,b2 in zip(A.tolist(),B1,B2)]
Out[479]: [[2, 3, 4, 5], [5, 7], [2, 1]]
也可以将2个列表转换为1d索引的数组,然后从A.ravel()
中选择值。这将产生一个1d数组,例如
array([2, 3, 4, 5, 5, 7, 2, 1]
理论上可能是np.split
- 但最近对其他问题的经验表明,这并没有节省太多时间。
如果行选择的长度都相同,我们可以得到一个二维数组。迭代版本每行占用2个元素:
In [482]: np.array([a[b1:b1+2] for a,b1 in zip(A,B1)])
Out[482]:
array([[2, 3],
[5, 7],
[2, 1]])
我在之前的SO问题中讨论了如何通过一个索引操作产生这种结果。
关于slice
接受的内容:
In [486]: slice([1,2],[3,4]).indices(10)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-486-0c3514e61cf6> in <module>()
----> 1 slice([1,2],[3,4]).indices(10)
TypeError: slice indices must be integers or None or have an __index__ method
&#39;矢量&#39; ravel索引
In [505]: B=np.array([B1,B2])
In [506]: bb=A.shape[1]*np.arange(3)+B
In [508]: ri =np.r_[tuple([slice(i,j) for i,j in bb.T])]
# or np.concatenate([np.arange(i,j) for i,j in bb.T])
In [509]: ri
Out[509]: array([ 1, 2, 3, 4, 7, 8, 13, 14])
In [510]: A.ravel()[ri]
Out[510]: array([2, 3, 4, 5, 5, 7, 2, 1])
它仍然有一个迭代 - 生成进入np.r_
的切片(将它们扩展为单个索引数组)