Numpy:有效的“碰撞”数组索引数组

时间:2014-05-01 01:32:32

标签: python arrays numpy scipy

给定n中的0 ... k-1个索引数组(即A = [0, 0, 1, 2, 1, ...]),形成新形状(n, k) {{1}数组的最有效方法是什么如果B如果B[i,j] = 1A[i] == j,那么{/ 1}}

即,对于示例A[i] = 0 A = [0, 0, 1, 2, 1, ...],我们会得到

(k=3)

如果没有明确的for循环,有没有办法做到这一点?

3 个答案:

答案 0 :(得分:3)

import numpy as np

A = np.array([0, 0, 1, 2, 1])

B = np.zeros((len(A), 3), dtype=np.int)

B[np.arange(len(A)), A] = 1

结果:

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

答案 1 :(得分:3)

鉴于您构建的数组的稀疏性,您可能希望使用Scipy的稀疏矩阵,这样可以减少内存占用:

import numpy
from scipy import sparse

A = numpy.array([0, 0, 1, 2, 1])
k = 3
B = sparse.coo_matrix((numpy.full(len(A), 1, dtype=int), (numpy.arange(len(A)), A)), shape=(len(A), k))

Scipy's documentation中描述了coo_matrix())。这给出了预期的结果:

>>> B.todense()
matrix([[ 1.,  0.,  0.],
        [ 1.,  0.,  0.],
        [ 0.,  1.,  0.],
        [ 0.,  0.,  1.],
        [ 0.,  1.,  0.]])

但内存占用量很小(如果k足够大[大于几个单位])。为了节省更多内存,上面的dtype可以缩小(取决于您的确切需求),dtype=numpy.int8甚至dtype=bool

答案 2 :(得分:0)

A=np.array([0, 0, 1, 2, 1])
n=5
k=3
B=np.zeros(n*k, 'int')
B[np.arange(n)*k+A]=1
B.reshape((n,k))

结果:

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