簡體   English   中英

使用2d numpy數組切片3d numpy數組

[英]slice a 3d numpy array using a 2d numpy array

是否可以使用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不同長度的?

Numpy針對具有固定尺寸的齊次數字數組進行了優化,因此它不支持變化的行或列大小。

但是,您可以通過使用數組列表來實現所需的功能:

Out = [A[i, B1[i]:B2[i]+1] for i in range(len(B1))]

這是 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

您想要的結果在每一行中都有不同數量的術語-這有力地表明不可能進行完全矢量化的解決方案。 對於每一行或每一列,它都沒有做相同的事情。

其次, 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]]

這兩個列表也可以轉換為一A.ravel()數組,然后從A.ravel()選擇值。 那將產生一維數組,例如

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

“向量化”旅行索引

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_的切片(將它們擴展為單個索引數組)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM