簡體   English   中英

用2D數組numpy索引3D數組

[英]Index a 3D array with 2D array numpy

我試圖操縱這樣的索引和源數組:

結果[i] [j] [k] =源[i] [索引[i] [j] [k]]

我知道如何使用for循環來做到這一點,但是我正在使用巨型數組,並且我想使用更省時的方法。 我嘗試使用numpy的高級索引,但是我不太了解。

功能示例:

source = [[0.0  0.1  0.2  0.3]
          [1.0  1.1  1.2  1.3]
          [2.0  2.1  2.2  2.3]]

indices = [[[3 1 0 1]
            [3 0 0 3]]

           [[0 1 0 2]
            [3 2 1 1]]

           [[1 1 0 1]
            [0 1 2 2]]]

# result[i][j][k] = source[i][indices[i][j][k]]

result = [[[0.3  0.1  0.0  0.1]
           [0.3  0.0  0.0  0.3]]

          [[1.0  1.1  1.0  1.2]
           [1.3  1.2  1.1  1.1]]

          [[2.1  2.1  2.0  2.1]
           [2.0  2.1  2.2  2.2]]]

使用整數高級索引的解決方案:

鑒於:

source = [[0.0,  0.1,  0.2,  0.3],
          [1.0,  1.1,  1.2,  1.3],
          [2.0,  2.1,  2.2,  2.3]]

indices = [[[3, 1, 0, 1],
           [3, 0, 0, 3]],
          [[0, 1, 0, 2],
          [3, 2, 1, 1]],
          [[1, 1, 0, 1],
          [0, 1, 2, 2]]]

用這個:

import numpy as np
nd_source = np.array(source)

source_rows = len(source)      # == 3, in above example
source_cols = len(source[0])   # == 4, in above example

row_indices = np.arange(source_rows).reshape(-1,1,1)
result = nd_source [row_indices, indices]

結果:

print (result)
[[[0.3 0.1 0.  0.1]
  [0.3 0.  0.  0.3]]

 [[1.  1.1 1.  1.2]
  [1.3 1.2 1.1 1.1]]

 [[2.1 2.1 2.  2.1]
  [2.  2.1 2.2 2.2]]]

說明:

要使用Integer Advanced Indexing,關鍵規則是:

  1. 我們必須提供由整數索引組成的索引數組。
  2. 我們必須提供盡可能多的索引數組,就像源數組中有維一樣。
  3. 這些索引數組的形狀必須相同,或者至少所有索引數組都可以廣播為單個最終形狀。

整數高級索引的工作方式是:

給定源數組具有n維,因此我們提供了n整數索引數組:

  1. 所有這些索引數組,如果不是相同的統一形狀,將被廣播為單一的統一形狀。
  2. 要訪問源數組中的任何元素,顯然我們需要一個n元組的索引。 因此,要從源數組生成結果數組,我們需要幾個n元組,最終結果數組的每個元素位置都需要一個n元組。 對於結果數組的每個元素位置,將從廣播的索引數組中的相應元素位置構造索引的n個元組。 (如上所述,請記住結果數組的形狀與廣播索引數組的形狀完全相同)。
  3. 因此, 通過串聯遍歷索引數組 ,我們得到了生成結果數組所需的所有n個元組,其形狀與廣播的索引數組相同。

將此解釋應用於以上示例:

  1. 我們的源數組是nd_source = np.array(source) ,它是2d。
  2. 我們的最終結果形狀為(3,2,4)

  3. 因此,我們需要提供2索引數組,並且這些索引數組必須為(3,2,4)的最終結果形狀,或者可以廣播為(3,2,4)形狀。

  4. 我們的第一個索引數組是row_indices = np.arange(source_rows).reshape(-1,1,1) source_rows是源中的行數,在本示例中為3 )。此索引數組的形狀為(3,1,1) ,實際上看起來像[[[0]],[[1]],[[2]]] 這可以廣播為最終結果形狀(3,2,4) ,並且廣播的數組看起來像[[[0,0,0,0],[0,0,0,0]],[[1,1,1,1],[1,1,1,1]],[[2,2,2,2],[2,2,2,2]]]

  5. 我們的第二個索引數組是indices 盡管這不是數組,而只是列表的列表,但是當我們將其作為發送索引數組傳遞時,numpy足夠靈活,可以自動將其轉換為相應的ndarray。 請注意,即使沒有任何廣播,此數組也已經具有(3,2,4)的最終期望結果形狀。

  6. 遍歷串聯這兩個索引陣列(一個廣播的陣列,而另一個用作是),生成numpy的訪問我們的源2D陣列所需要的所有2元組nd_source ,並生成在所述形狀的最終結果(3,2,4)

暫無
暫無

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

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