Is there a way to slice the array below without having to define the row indices i.e. not having to write range(len(X))
?
是否有一种方法可以在不需要定义行索引的情况下分割下面的数组,即不需要写入范围(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]切片是可能的,但看起来不是。
3 个解决方案
#1
3
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)
. As of numpy 1.9.0, np.arange
approach is faster:
性能说明:虽然这个解决方案直接回答了这个问题,但是随着len(X)的增加,它很快就不是最优的了。从1。9。0到np。不等方法更快:
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,))
#2
#3
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])
#1
3
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)
. As of numpy 1.9.0, np.arange
approach is faster:
性能说明:虽然这个解决方案直接回答了这个问题,但是随着len(X)的增加,它很快就不是最优的了。从1。9。0到np。不等方法更快:
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,))
#2
1
You take the diagonal elements of X[:,L]
using diag
(or diagonal
):
取X[:,L]的对角线元素diag(或对角线):
np.diag(X[:,L])
Another way to do it is with where
:
另一种方法是使用where:
np.where(L,X[:,1],X[:,0])
#3
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])