2015-01-20 23 views
1

我想從某個向量x=(x_1,x_2, ..., x_I)獲得矩陣,其中矩陣中的每一行對應於x(i) := (x_1,...,x_{i-1},x_{i+1},...,x_I)python leave-one-out估計

我知道

from sklearn.cross_validation import LeaveOneOut 
I = 30 
myrowiterator = LeaveOneOut(I) 
for eachrow, _ in myrowiterator: 
    print(eachrow) # prints [1,2,...,29] 
         #  [0,2,...,29] and so on ... 

提供一個例程,以獲得每一行用於上述基質。但我寧願直接在一個步驟中獲得矩陣,直接在這個矩陣上操作,而不是循環遍歷它的行。這會爲我節省一些計算時間。

回答

3

既然你有numpy的標籤,以下工作:

>>> N = 5 
>>> idx = np.arange(N) 
>>> idx = idx[1:] - (idx[:, None] >= idx[1:]) 
>>> idx 
array([[1, 2, 3, 4], 
     [0, 2, 3, 4], 
     [0, 1, 3, 4], 
     [0, 1, 2, 4], 
     [0, 1, 2, 3]]) 

,現在您可以使用該索引任何其他數組:

>>> a = np.array(['a', 'b', 'c', 'd', 'e']) 
>>> a[idx] 
array([['b', 'c', 'd', 'e'], 
     ['a', 'c', 'd', 'e'], 
     ['a', 'b', 'd', 'e'], 
     ['a', 'b', 'c', 'e'], 
     ['a', 'b', 'c', 'd']], 
     dtype='|S1') 

編輯由於@ user3820991暗示,這可以做成一個

>>> N = 5 
>>> idx = np.arange(1, N) - np.tri(N, N-1, k=-1, dtype=bool) 
>>> idx 
array([[1, 2, 3, 4], 
     [0, 2, 3, 4], 
     [0, 1, 3, 4], 
     [0, 1, 2, 4], 
     [0, 1, 2, 3]]) 

功能np.tri實際上是在此答案的第一版本的神奇比較的高度優化的版本,因爲它使用的最小可能的int類型的數組的大小:通過寫它作爲少隱蔽,因爲numpy的比較使用SIMD進行矢量化,所以類型越小,操作越快。

+0

哇(+1)。我認爲如果答案中包含了對idx [1:] - (idx [:, None]> = idx [1:])魔法的直觀解釋,那將會非常棒。 :-) – NPE 2015-01-21 09:28:09

+0

啊,我明白了。非常好。 '(idx [:, None]> = idx [1:])'與np.tril(np.ones((N,N-1)),k = -1)'基本相同。謝謝。 – user3820991 2015-01-21 10:15:25

+1

但是魔術師永遠不會透露它的祕密,@NPE! ;-)我最後的編輯確實提供了一個相同的事物的可讀性更高的版本。 – Jaime 2015-01-21 15:05:06

1

下面將做到這一點:

In [31]: np.array([row for row, _ in LeaveOneOut(I)]) 
Out[31]: 
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], 
     [ 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], 
     [ 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], 
     [ 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], 
     ... 
     [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28]]) 
+0

依然依賴循環。我只是認爲必須有一些直接提供這種功能的功能。但我接受了。非常感謝! – user3820991 2015-01-20 22:31:27

+0

@ user3820991:你可以沿着這些方向做些什麼:http://stackoverflow.com/questions/17527693/transform-the-upper-lower-triangular-part-of-a-symmetric-matrix-2d-array-into ?lq = 1,但我現在沒有精力去完成它。 : -/ – NPE 2015-01-20 22:38:02