简体   繁体   English

按列索引切片numpy.ndarray

[英]Slicing numpy.ndarray by column index

Is there a way to slice the array below without having to define the row indices ie not having to write range(len(X)) ? 有没有一种方法可以切片下面的数组而不必定义行索引,即不必写range(len(X))

X = np.arange(10*2).reshape((10,2))
L = np.random.randint(0,2,10)

Xs = X[range(len(X)),L]

I thought it was possible to slice with X[:,L] but looks like it's not. 我以为可以用X[:,L]切片,但看起来好像不是。

You're probably looking for np.choose : 您可能正在寻找np.choose

In [25]: X = np.arange(10*2).reshape((10,2)); X
Out[25]: 
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11],
       [12, 13],
       [14, 15],
       [16, 17],
       [18, 19]])

In [26]: L = np.random.randint(0,2,10); L
Out[26]: array([1, 1, 1, 1, 1, 0, 0, 0, 0, 1])

In [27]: L.choose(X.T)
Out[27]: array([ 1,  3,  5,  7,  9, 10, 12, 14, 16, 19])

In [28]: # or otherwise

In [29]: np.choose(L, X.T)
Out[29]: array([ 1,  3,  5,  7,  9, 10, 12, 14, 16, 19])

Performance note : while this solution is a direct answer to the question, it's quickly becomes not the most optimal with increase of len(X) . 性能说明 :尽管此解决方案是对问题的直接答案,但随着len(X)增加,它很快就变得不是最佳的。 As of numpy 1.9.0, np.arange approach is faster: 从numpy 1.9.0开始, np.arange方法更快:

In [17]: %timeit X[range(len(X)), L]
1000 loops, best of 3: 629 µs per loop

In [18]: %timeit X[np.arange(len(X)), L]
10000 loops, best of 3: 78.8 µs per loop

In [19]: %timeit L.choose(X.T)
10000 loops, best of 3: 146 µs per loop

In [20]: X.shape, L.shape
Out[20]: ((10000, 2), (10000,))

You take the diagonal elements of X[:,L] using diag (or diagonal ): 您可以使用diag (或diagonal )获取X[:,L]的对角线元素:

np.diag(X[:,L])

Another way to do it is with where : 另一种方法是在where

np.where(L,X[:,1],X[:,0])

Note that 注意

In [9]: X[:, L]
Out[9]:
array([[ 1,  1,  0,  0,  1,  0,  1,  0,  1,  0],
   [ 3,  3,  2,  2,  3,  2,  3,  2,  3,  2],
   [ 5,  5,  4,  4,  5,  4,  5,  4,  5,  4],
   [ 7,  7,  6,  6,  7,  6,  7,  6,  7,  6],
   [ 9,  9,  8,  8,  9,  8,  9,  8,  9,  8],
   [11, 11, 10, 10, 11, 10, 11, 10, 11, 10],
   [13, 13, 12, 12, 13, 12, 13, 12, 13, 12],
   [15, 15, 14, 14, 15, 14, 15, 14, 15, 14],
   [17, 17, 16, 16, 17, 16, 17, 16, 17, 16],
   [19, 19, 18, 18, 19, 18, 19, 18, 19, 18]])

And you want the diagonal elements: 您想要对角线元素:

So just do: 所以做:

In [14]: X[:, L].diagonal()
Out[14]: array([ 1,  3,  4,  6,  9, 10, 13, 14, 17, 18])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM