2010-01-21 32 views
6

我想爲numpy數組的每一行選擇特定的列元素。例如,在下面的例子:從數組中選擇每一行中的特定列

In [1]: a = np.random.random((3,2)) 
Out[1]: 
array([[ 0.75670668, 0.1283942 ], 
     [ 0.51326555, 0.59378083], 
     [ 0.03219789, 0.53612603]]) 

我想選擇第一行的第一個元素,第二行的第二元素,和第三行的第一個元素。於是,我就做到以下幾點:

In [2]: b = np.array([0,1,0]) 

In [3]: a[:,b] 

但是,這將產生以下輸出:

Out[3]: 
array([[ 0.75670668, 0.1283942 , 0.75670668], 
     [ 0.51326555, 0.59378083, 0.51326555], 
     [ 0.03219789, 0.53612603, 0.03219789]]) 

這顯然不是我所期待的。有沒有簡單的方法來做我想做的事情而不使用循環?

回答

8

您可以使用:

a[np.arange(3), (0,1,0)] 

在你上面的例子。

+0

確實。 *切片*保留給定的軸原樣,而您要求的兩個維度在文檔中稱爲*花式索引*。 – dwf 2010-01-21 23:36:17

+0

對。例如,'a [0:2,0:2]'和'a [[0,1],[0,1]]'返回不同的東西。 – 2010-01-24 04:31:54

2

這不是一個答案,而是嘗試記錄這一點。對於上面的答案,我們將有:

>>> import numpy as np 
>>> A = np.array(range(6)) 
>>> A 
array([0, 1, 2, 3, 4, 5]) 
>>> A.shape = (3,2) 
>>> A 
array([[0, 1], 
     [2, 3], 
     [4, 5]]) 
>>> A[(0,1,2),(0,1,0)] 
array([0, 3, 4]) 

指定各行的列表(或元組)和列座標允許看中的索引數組。起初,評論中的第一個例子看起來很相似,但索引是切片。他們不擴大在整個範圍,形狀返回數組的是不同的:

>>> A[0:2,0:2] 
array([[0, 1], 
     [2, 3]]) 

對於註釋的第二個例子

>>> A[[0,1],[0,1]] 
array([0, 3]) 

如此看來,片是不同的,但除此之外,無論索引如何構建,您都可以指定元組或列表(x值,y值),並從數組中恢復這些特定元素。

3

OK,只是在這裏澄清,讓我們做一個簡單的例子

A=diag(arange(0,10,1)) 

array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
     [0, 1, 0, 0, 0, 0, 0, 0, 0, 0], 
     [0, 0, 2, 0, 0, 0, 0, 0, 0, 0], 
     [0, 0, 0, 3, 0, 0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 4, 0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0, 5, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0, 0, 6, 0, 0, 0], 
     [0, 0, 0, 0, 0, 0, 0, 7, 0, 0], 
     [0, 0, 0, 0, 0, 0, 0, 0, 8, 0], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 9]]) 

然後

A[0][0:4] 

array([0, 0, 0, 0]) 

即第一行中,元素0至3。但

A[0:4][1] 

不給所述第一4行,在每個第二元件。相反,我們得到

array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) 

即整個第二列。

A[0:4,1] 

array([0, 1, 0, 0]) 

我敢肯定有一個很好的理由,並且可以完美的程序員 但對於我們這些在這個偉大的宗教門外漢它可以相當混亂。

+0

A [0:4]創建一個新的形狀數組(4,10)。用A [0:4,y],你要求數組的第二維,而對於A [0:4] [x],你要求新數組的第一維!如果它可以幫助你看到什麼時候要求暗淡1或暗淡2,你可以寫出它[A:0:4,:] [1 ,:]。 – bendaizer 2013-05-24 16:03:27

+0

使用diag最終會讓你和其他人更容易混淆,因爲實際上'A [ 0:4] [1]'給了你第二行*,而不是第二列。 – 2016-08-07 07:27:17