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

Python 基于不带for循环的1D数组中的值更改2D numpy数组中的某些值,python,arrays,numpy,for-loop,Python,Arrays,Numpy,For Loop,我的问题对我来说太基本了,以至于我有点不好意思自己没有解决它。尽管进行了咨询,但我还是不知道如何基于1D numpy数组中的值更改2D numpy数组中的某些值,而不使用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)

我的问题对我来说太基本了,以至于我有点不好意思自己没有解决它。尽管进行了咨询,但我还是不知道如何基于1D numpy数组中的值更改2D numpy数组中的某些值,而不使用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]]
具有预期结果的示例案例如下:

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]]
这是什么原因造成的?还有,如何实现加速?

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

看起来实际上被屏蔽的数组速度很慢。看

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

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


希望它能解决您的疑问。

谢谢您的回答。由于我的实际应用程序有点复杂,如果我成功地实现了您的解决方案,我将与您联系。不过看起来很有希望!抱歉耽搁了。不幸的是,我得到了一个
索引器:索引3超出了轴0的范围,大小为3
,即使在将代码应用到示例时也是如此。然而,对示例有效的是
a[range(r),b]=c[range(r),b]*0.9
我看不到
arange
,删除了下一票:)。
np.arange
确实加快了代码的速度,的确谢谢你的帮助。