2017-07-20 15 views
2

可以說我有一些2D陣列a = np.ones((3,3))的Python:彈力2D陣列轉換成3D基於對應與第三維陣列索引

欲這個數組伸入3米的尺寸。我有數組b,與a的大小相同,它提供了第3維中的索引,即a中的每個對應元素都需要去。

我也有3D陣列c,它充滿了NaNs。這是來自a的信息應該放入的數組。剩下的空格是沒有得到「裝:可以保持NaN的

>>> a = np.ones((3,3)) 
>>> b = np.random.randint(0,3,(3,3)) 
>>> c = np.empty((3,3,3))*np.nan 
>>> 
>>> a 
array([[ 1., 1., 1.], 
     [ 1., 1., 1.], 
     [ 1., 1., 1.]]) 
>>> b 
array([[2, 2, 2], 
     [1, 0, 2], 
     [1, 0, 0]]) 
>>> c 
array([[[ nan, nan, nan], 
     [ nan, nan, nan], 
     [ nan, nan, nan]], 

     [[ nan, nan, nan], 
     [ nan, nan, nan], 
     [ nan, nan, nan]], 

     [[ nan, nan, nan], 
     [ nan, nan, nan], 
     [ nan, nan, nan]]]) 

所以,在上面的例子中,我想用C [0,0,2] = 1

結束了。

我知道我可能有一些嵌套循環做到這一點,但最好我要以更有效的/量化的方式完成這件事

回答

7

您可以使用花哨的索引,因爲這,假設b最大值總是小於c.shape[2]

n1, n2 = a.shape 
c[np.arange(n1)[:,None], np.arange(n2), b] = a 

c 
#array([[[ nan, nan, 1.], 
#  [ nan, nan, 1.], 
#  [ nan, nan, 1.]], 

#  [[ nan, 1., nan], 
#  [ 1., nan, nan], 
#  [ nan, nan, 1.]], 

#  [[ nan, 1., nan], 
#  [ 1., nan, nan], 
#  [ 1., nan, nan]]]) 

在這裏我們使用整數數組爲所有的維觸發advanced indexing,三個陣列如下彼此廣播(這裏我們使用numpy.broacast_arrays想象這):

i, j, k = np.broadcast_arrays(np.arange(3)[:,None], np.arange(3), b) 

print("first dimension index: ") 
print(i) 
print("second dimension index: ") 
print(j) 
print("third dimension index: ") 
print(k) 

first dimension index: 
[[0 0 0] 
[1 1 1] 
[2 2 2]] 
second dimension index: 
[[0 1 2] 
[0 1 2] 
[0 1 2]] 
third dimension index: 
[[2 2 2] 
[1 0 2] 
[1 0 0]] 

現在高級索引變爲(0,0,2),(0,1,2),(0,2,2)...,即接從在相同的位置中的每個陣列的一個值,以形成用於一個元素的索引:


一些測試的情況:

c[0,0,2] 
#1.0 

c[0,1,2] 
#1.0 

c[2,1,0] 
#1.0 
+0

兩者都可以工作,但是這種方法比喬納斯·阿德勒的方法更快。你能解釋一下到底發生了什麼嗎? – hm8

+1

@ user3826115:B提供第三維的索引 - 「arange」提供另外兩個索引。 – Eric

3

好了,所以這種感覺就像一個總劈,但確實特技:

a = np.ones((3,3)) 
b = np.array([[2, 2, 2], 
       [1, 0, 2], 
       [1, 0, 0]]) 
c = np.empty((3,3,3))*np.nan 

z_coords = np.arange(3) 

c[z_coords[None, None, :] == b[..., None]] = a.ravel() 

我要做的就是創建一個布爾數組的索引是因爲我們要分配的指標真的,然後將這些。

array([[[ nan, nan, 1.], 
     [ nan, nan, 1.], 
     [ nan, nan, 1.]], 

     [[ nan, 1., nan], 
     [ 1., nan, nan], 
     [ nan, nan, 1.]], 

     [[ nan, 1., nan], 
     [ 1., nan, nan], 
     [ 1., nan, nan]]]) 
1

較慢的但更清楚也許選項:

x, y = np.indices(c.shape[:2]) 
c[x, y, b] = a # same as looping over c[x[i,j], y[i,j], b[i,j]] = a[i,j] 

訣竅是產生都具有相同的形狀索引的3個數組 - 一個用於的c每個維度。

接受的答案基本上是這樣做的,但利用廣播