我有两个numpy数组。我想在consume
函数中使用数组p
的每一行中的值作为数组food
的索引。不幸的是,当p
达到2000
行的大小时,使用for
循环需要很长时间。
在consume
函数中会有比for
循环更快的替代方法吗?我将感谢任何人帮助我解决这个问题。
import numpy as np
dt = 0.1
k = 2
p = np.array([[50, 50, 50],
[ 0, 0, 0],
[51, 51, 50],
[52, 50, 51],
[52, 51, 51],
[50, 49, 49],
[50, 49, 48],
[51, 50, 50],
[49, 49, 50],
[53, 49, 51],
[50, 51, 50],
[51, 52, 51]])
food = np.ones((101, 101, 101))
def consume():
for i in range(1, p.shape[0]):
e = p[i - 1:i]
food[e[0, 0], e[0, 1], e[0, 2]] -= dt * k
consume()
发布于 2021-04-23 00:02:41
阅读Indexing Multi-Dimensional Arrays
基本上,如果你想从食物中访问food[x1, y1, z1]
,food[x2, y2, z2]
... food[xn, yn, zn]
值,你可以使用food[[x1, x2, .. , xn], [y1, y2, .., yn], [z1, z2, .., zn]]
使用:
food[p[:, 0], p[:, 1], p[:, 2]] -= dt*k
发布于 2021-04-23 00:52:40
在这里,您根本不需要循环。奇特的索引将允许您通过转置p
并将其转换为tuple
来精确地执行您想要的操作。
如果您没有副本,只需按原样使用索引:
food = np.ones((101, 101, 101))
food[tuple(p[:-1].T)] -= dt * k
我不确定为什么你会以如此奇怪的方式迭代。范围在上界上是排他的。要遍历p
的所有行,只需使用for i in range(p.shape[0]):
,甚至只需使用for i in range(len(p)):
。你甚至可以做for e in p:
。如果这确实是您想要的,则不需要在上面的表达式中设置p
的子集:
food[tuple(p.T)] -= dt * k
此外,当您可以执行e = p[i - 1]
(或者只使用i
,或者将其设置为循环变量)时,不需要对e = p[i - 1:i]
进行索引。然后,您可以将其赋值给food[tuple(e)] = ...
,而不是2D索引。
如果p
中有重复的索引,您可以使用np.subtract.at
处理它们
np.subtract.at(food, tuple(p[:-1].T), dt * k)
此操作是无缓冲的,因此它将通过将重复索引减去两次来实现。它可以就地工作。
https://stackoverflow.com/questions/67222042
复制相似问题