【问题标题】:Numpy: efficient array of indices to "bump" arrayNumpy:“bump”数组的有效索引数组
【发布时间】:2014-05-01 01:32:32
【问题描述】:

给定0 ... k-1 中长度为n 的索引数组(即A = [0, 0, 1, 2, 1, ...]),形成一个新的形状(n, k) B 数组的最有效方法是什么,例如B[i,j] = 1 如果@ 987654327@ 和 A[i] = 0 否则?

即,例如A = [0, 0, 1, 2, 1, ...](k=3),我们会得到

B = [[1, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 1, 0], ...]

有没有办法在没有明确的 for 循环的情况下做到这一点?

【问题讨论】:

    标签: python arrays numpy scipy


    【解决方案1】:

    鉴于您构建的数组的稀疏性,您可能希望使用 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))
    

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

    >>> 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

    【讨论】:

    • 您关于内存的观点是有效的,并且适用于非常稀疏的矩阵(在这种情况下为大 k)。但是,必须小心。在上面的例子中,dtype可以是int8,而稀疏矩阵的行和列的dtype是int32(启发我,我们可以改变它)。对于我们的小例子,密集矩阵占用 15 个字节,而稀疏矩阵占用 45 个字节,数据:5 个字节,行:20 个字节,列:20 个字节。在 OP 的情况下,如果 k > 9 比 sparse 会节省内存。
    • 好点。我添加了一个关于内存占用和k 值之间关系的警告。
    【解决方案2】:
    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]])
    

    【讨论】:

      【解决方案3】:
      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]])
      

      【讨论】:

      • 这行得通,但这不必要地令人费解,正如 Akavall 的回答所示(NumPy 提供了在特定 2D 坐标处分配值的能力,所以好的代码应该使用它,因为它更容易/更快地阅读)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 1970-01-01
      • 2016-04-08
      • 2021-04-17
      • 1970-01-01
      相关资源
      最近更新 更多