【问题标题】:numpy array indexing: different columns of each rownumpy数组索引:每行的不同列
【发布时间】:2021-07-21 19:25:15
【问题描述】:

我正在为 np 数组索引而苦苦挣扎。

假设我们有一个名为 a 的数组。

import numpy as np
a = np.ones((10000,100))

还有一个名为idx的数组

idx = np.random.randint(low=0, high=a.shape[1], size=a.shape[0])

现在我想做的是将idx 中的 a 的每一列都增加一个,使用一个看起来像这样的 for 循环:

for k, i in enumerate(idx):
    a[k][i] += 1

有没有办法使用索引来做到这一点,例如,我知道

a[:,0] += 1

将 a 的每一列都增加一个,但是我们如何对不同的列做到这一点?

希望我的问题很清楚

【问题讨论】:

    标签: python arrays numpy indexing


    【解决方案1】:

    你可以试试:

    import numpy as np
    
    a = np.ones((10000, 100))
    a[:, 0] += 1
    np.random.shuffle(np.transpose(a))
    print(a)
    

    解释:

    1. 导入必要的库:
    import numpy as np
    
    1. 定义你的数组:
    a = np.ones((10000, 100))
    
    1. 1 添加到数组第一列中的每个数字:
    a[:, 0] += 1
    
    1. 随机排列数组的每一列:
    np.random.shuffle(np.transpose(a))
    

    【讨论】:

    • 我认为这根本不是他想要做的......基本上如果随机数组是 [1, 49, 4] 则循环在第 1 列增加一,第 49 列和第 4 列。您也可以有两倍相同的数字,例如[1, 1, 4, 98, 43, 1] 从而导致多个增量。
    • @Mathieu 正如 OP 所说,他们的代码有效,但他们想以另一种方式做到这一点。因此,如果您运行 OP 的代码,您将看到一个由1s 组成的数组,每行随机位置有一个2
    • 感谢您的回答!我想我应该更清楚一点,idx 在这个例子中是随机的,但不是我的实际工作示例
    【解决方案2】:

    正如问题标题中所建议的,它可以通过数组索引来完成。

    import numpy as np 
    a = np.ones((20,10))                                                   
    
    idx = np.random.randint(low=0, high=a.shape[1], size=a.shape[0])
    idx                                                                    
    # array([5, 0, 7, 3, 8, 7, 5, 1, 8, 8, 8, 8, 6, 9, 2, 4, 8, 4, 4, 7])
    
    a[ np.arange( a.shape[0] ), idx ] += 1     # Array indexing
    
    a  
    # array([[1., 1., 1., 1., 1., 2., 1., 1., 1., 1.],
    #        [2., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
    #        [1., 1., 1., 1., 1., 1., 1., 2., 1., 1.],
    #        [1., 1., 1., 2., 1., 1., 1., 1., 1., 1.],
    #        [1., 1., 1., 1., 1., 1., 1., 1., 2., 1.],
    #        [1., 1., 1., 1., 1., 1., 1., 2., 1., 1.],
    #        [1., 1., 1., 1., 1., 2., 1., 1., 1., 1.],
    #        [1., 2., 1., 1., 1., 1., 1., 1., 1., 1.],
    #        [1., 1., 1., 1., 1., 1., 1., 1., 2., 1.],
    #        [1., 1., 1., 1., 1., 1., 1., 1., 2., 1.],
    #        [1., 1., 1., 1., 1., 1., 1., 1., 2., 1.],
    #        [1., 1., 1., 1., 1., 1., 1., 1., 2., 1.],
    #        [1., 1., 1., 1., 1., 1., 2., 1., 1., 1.],
    #        [1., 1., 1., 1., 1., 1., 1., 1., 1., 2.],
    #        [1., 1., 2., 1., 1., 1., 1., 1., 1., 1.],
    #        [1., 1., 1., 1., 2., 1., 1., 1., 1., 1.],
    #        [1., 1., 1., 1., 1., 1., 1., 1., 2., 1.],
    #        [1., 1., 1., 1., 2., 1., 1., 1., 1., 1.],
    #        [1., 1., 1., 1., 2., 1., 1., 1., 1., 1.],
    #        [1., 1., 1., 1., 1., 1., 1., 2., 1., 1.]])
    

    np.arange( a.shape[0] ) 对应每一行,idx 是列索引。

    【讨论】:

    • 谢谢!我缺少的 np.arange 部分,这就是为什么我无法让它工作
    【解决方案3】:

    另一种方法是线性化索引(此算法与 MATLAB 兼容):

    import numpy as np
    a = np.ones((10,5))
    
    col = np.random.randint(low=0, high=a.shape[1], size=a.shape[0])
    
    # linearizing indices: idx = col + row * L; L -> total number of columns
    idx = col + np.arange(a.shape[0]) * a.shape[1]
    a[np.unravel_index(idx,a.shape)] += 1
    
    print(a)
    

    生成

    [[2. 1. 1. 1. 1.]
     [1. 2. 1. 1. 1.]
     [1. 2. 1. 1. 1.]
     [1. 1. 1. 1. 2.]
     [1. 1. 1. 1. 2.]
     [1. 1. 1. 2. 1.]
     [2. 1. 1. 1. 1.]
     [2. 1. 1. 1. 1.]
     [1. 1. 1. 1. 2.]
     [2. 1. 1. 1. 1.]]
    

    【讨论】:

      猜你喜欢
      • 2021-08-21
      • 1970-01-01
      • 1970-01-01
      • 2018-12-19
      • 2018-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多