代码之家  ›  专栏  ›  技术社区  ›  apitsch

基于无for循环的1D数组中的值更改2D numpy数组中的某些值

  •  2
  • apitsch  · 技术社区  · 8 年前

    我的问题对我来说太基本了,我有点不好意思自己没有解决。尽管咨询过 this , this 和 that ,我不知道如何在不使用for循环的情况下根据1D numpy数组中的值更改2D numpy数组中的某些值。

    具有预期结果的一个例子是:

    import numpy as np
    
    # sample data:
    a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    b = np.array([2, 0, 2])
    c = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
    
    # for-loop solution:
    for i in range(len(a)):
        a[i][b[i]] = 0.9 * c[i][b[i]]
    
    # desired result:
    print(a)
    # [[ 1  2 27]
    #  [36  5  6]
    #  [ 7  8 81]]
    

    编辑1

    在对Rafael的答案进行修改之后,我现在得到了期望的结果,而没有for循环。然而,令我惊讶的是,索引解决方案是 更慢的 而不是for循环。

    import numpy as np
    import time
    
    # set seed for reproducibility:
    np.random.seed(1)
    
    x = np.random.randint(10, size=(10, 10))
    y = np.random.randint(10, size=10)
    z = np.random.randint(10, size=(10, 10))
    
    # for-loop solution:
    start1 = time.clock()
    for i in range(len(x)):
         x[i][y[i]] = 2 * z[i][y[i]]
    end1 = time.clock()
    print("time loop: " + str(end1 - start1))
    # time loop: 0.00045699999999726515
    print("result for-loop:")
    print(x)
    # result for-loop:
    # [[ 5  8  9  5  0  0  1  7  6  4]
    #  [12  4  5  2  4  2  4  7  7  9]
    #  [ 1  7  2  6  9  9  7  6  9  1]
    #  [ 2  1  8  8  3  9  8  7  3  6]
    #  [ 5  1  9  3  4  8  1 16  0  3]
    #  [ 9 14  0  4  9  2  7  7  9  8]
    #  [ 6  9  3  7  7  4  5  0  3  6]
    #  [ 8  0  2  7  7  9  7  3  0 16]
    #  [ 7  7  1  1  3  0  8  6 16  5]
    #  [ 6  2  5  7 14  4  4  7  7  4]]
    
    # set seed for reproducibility:
    np.random.seed(1)
    
    x = np.random.randint(10, size=(10, 10))
    y = np.random.randint(10, size=10)
    z = np.random.randint(10, size=(10, 10))
    
    # indexing solution:
    start2 = time.clock()
    r = x.shape[0]
    x[range(r), y] = z[range(r), y] * 2
    end2 = time.clock()
    print("time indexing: " + str(end2 - start2))
    # time indexing: 0.0005479999999948859
    print("result indexing:")
    print(x)
    # result indexing:
    # [[ 5  8  9  5  0  0  1  7  6  4]
    #  [12  4  5  2  4  2  4  7  7  9]
    #  [ 1  7  2  6  9  9  7  6  9  1]
    #  [ 2  1  8  8  3  9  8  7  3  6]
    #  [ 5  1  9  3  4  8  1 16  0  3]
    #  [ 9 14  0  4  9  2  7  7  9  8]
    #  [ 6  9  3  7  7  4  5  0  3  6]
    #  [ 8  0  2  7  7  9  7  3  0 16]
    #  [ 7  7  1  1  3  0  8  6 16  5]
    #  [ 6  2  5  7 14  4  4  7  7  4]]
    

    这是什么原因?还有,我怎样才能实现加速呢?

    2 回复  |  直到 8 年前
        1
  •  2
  •   rafaelc    8 年前

    IIUC公司

    r = np.arange(a.shape[0]) # same as range(len(a)) here, but faster.
    a[r, b] = c[r, b] * 0.9
    
    array([[ 1,  2, 27],
           [36,  5,  6],
           [ 7,  8, 81]])
    
        2
  •  0
  •   Abhishek Arya    8 年前

    看起来屏蔽阵列的速度很慢。见 here .

    这是用户在另一个答案中所说的。

    请记住,遮光比真实的更方便 解决方案。如果需要对数组执行密集计算 数组中缺少/未定义的值,在大多数情况下 亲自处理面具和数据。直到更好 在NumPy代码中烘焙缺少/未定义值的实现 (很快就会发生)你被蒙面射线困住了。 是的,它们非常慢,因为它们是用纯Python编写的 当然不能像依赖某些C代码那样高效

    希望它能解决你的疑问。