python - 如何使用 numpy 执行此复制操作?
问题描述
我一直在研究“扩散蒙特卡罗”的基本模拟,以找到氢分子的基态能量。算法的一个关键部分正在痛苦地减慢我的代码,我不知道如何修复它。
这就是代码正在做的事情。我有一个名为 x 的 6 x N numpy 数组。该阵列代表 N 个随机“步行者”,它们对 6 维相空间进行采样(两个电子乘以 3 维是 6 维)。我建议对每个“walker”进行某些随机更改以获得我的新“walker”,然后使用公式为每个新 walker 吐出一个数字“m”。
数字 m 可以是 0、1、2 或 3。这是困难的部分。如果 m 为 0,则它对应的“walker”将从数组中删除。如果 m 为 1,则步行者仍然存在。如果 m 是 2,那么 walker 仍然存在,我必须在数组中创建 walker 的新副本。如果 m 为 3,则步行者仍然存在,我必须在数组中制作步行者的两个新副本。此后代码重复;对我的步行者数组等提出了随机更改。
所以; 以下是减慢算法的代码。这是最后一部分的代码,我必须通过我的 m 并确定如何处理每个“walker”,并创建我的新数组 x 以用于算法的下一次迭代。
j1 = 0
n1 = len(x[0,:])
x_n = np.ones((6,2*n1))
for i in range(0,n1):
if m[i] == 1:
x_n[:,j1] = x[:,i]
j1 = j1 + 1
if m[i] == 2:
x_n[:,j1] = x[:,i]
x_n[:,j1+1] = x[:,i]
j1 = j1 + 2
if m[i] == 3:
x_n[:,j1] = x[:,i]
x_n[:,j1+1] = x[:,i]
j1 = j1 + 3
x = np.ones((6,j1))
for j in range(0,j1):
x[:,j] = x_n[:,j]
我的问题如下;有没有办法使用 numpy 本身来做我在这段代码中所做的事情?根据我的经验,Numpy 往往比 for 循环快得多。在变分蒙特卡罗模拟中直接使用 numpy,我能够在运行时间上实现 100 倍的改进。如果您想要完整的代码来实际运行算法,那么我可以发布它;它只是相当长。
解决方案
令 M 为每个随机游走者的 m 个值的 N x 1 数组。
让 X 成为您原来的 6 x N 数据数组
# np.where returns a list of indices where the condition is satisfied
zeros = np.where(M == 0) # don't actually need this variable, I just did it for completeness
ones = np.where(M == 1)
twos = np.where(M == 2)
threes = np.where(M == 3)
# use the lists of indices to access the relevant portions of X
ones_array = X[:,ones]
twos_array = X[:,twos]
threes_array = X[:,threes]
# update X with one copy where m = 1, two copies where m = 2, three copies where m = 3
X = np.concatenate((ones_array,twos_array,twos_array,threes_array,threes_array,threes_array),axis = 1)
这不会保留步行者的顺序,所以如果这很重要,代码会略有不同。
推荐阅读
- php - 多种实体类型的 Laravel 子域路由
- android - 如何使用 Flutter 实现非托管/非消耗性产品的应用内购买?
- python - 如何使这些图像分散在屏幕上?
- prometheus - 动态字段的总和
- ruby - 如何显示 ruby .gem 文件的内容?
- magento - Magento 2:在 phtml 中调用前端模板
- python-3.x - Tensorflow-Probability 中具有 3 个隐藏 DenseVariational 层的回归模型在训练期间返回 nan 作为损失
- bootstrap-4 - Laravel 8 Livewire CRUD 功能在部署到本地主机服务器后不起作用
- java - 尝试从中国环境访问 twilio API 时出错(握手期间远程主机关闭连接)
- spring-boot - 具有多个条件的 Elasticsearch 范围查询