python - 如何有效地更改矩阵/嵌套列表中的条目?
问题描述
对于蒙特卡罗模拟,我有 500 个 Person 实例,每个实例都有一个位置(笛卡尔坐标)作为属性。在整个模拟过程中,我需要多次访问两个人之间的距离。我已经定义了一个函数来计算两个人之间的(笛卡尔)距离(为简单起见,我们将此函数称为“距离(loc1,loc2)”)。我有兴趣使脚本在计算上更高效。我采取的第一步是创建一个对称矩阵来存储距离,而不是在每次需要时计算距离。现在我决定把它做成一个嵌套的 numpy 数组;如果它使事情变得更容易,我可以将其更改为嵌套列表或其他东西。(我使用这个的改编版本制作了矩阵:Python:使用列表理解生成对称数组)距离矩阵如下所示:
np.array([[0, 6.44177991, 2.74762143, 3.47162016, 2.0645646 ],
[6.44177991, 0, 1.59860905, 8.99027864, 2.58449879],
[2.74762143 , 1.59860905, 0, 2.06833575, 8.53594684],
[3.47162016, 8.99027864 , 2.06833575, 0, 6.76594943],
[2.0645646, 2.58449879, 8.53594684, 6.76594943, 0]])
在模拟过程中,人的位置(偶尔)会发生变化。发生这种情况时,我需要“更新”矩阵。我目前使用 for 循环(见下文)来解决这个问题,但我想知道是否有更有效的方法来替换这些值。
#note: population is a list containing the 500 Person entities
#e.g. if person5's location changes:
p_id = 5
for i in range(len(population)):
if i!=p_id:
new_distance=distance(population[i].location, population[p_id].location)
distance_matrix[p_id][i] = new_distance
distance_matrix[i][p_id] = new_distance
解决方案
尽管您没有要求它,但您可以使用 Numpy 的广播以非常简单的方式找到点之间的距离。这是通过np.newaxis
函数实现的,该函数只需向数组添加另一个(空)维度,以便对广播的数组执行算术运算(这样可以节省内存)。在下面的代码中,不需要循环,因为我们仅索引在每一步中更改(对应于修改后的人员位置)的距离矩阵的行(和列)。
我希望它确实比你最初的方法更有效(没有计时),尽管也许可以做进一步的优化(最后两行让我有点烦恼,不会撒谎)。
请注意,在下面的测试代码中,我假设您的Person
坐标显示在随机数组中x
,y
而 ,p_id
表示已更改位置的人员的索引。
import numpy as np
np.random.seed(1) # Fix seed for reproducibility
x = np.random.random(10) # Test x-coordinates array
y = np.random.random(10) # Test y-coordinates array
# Calculate distances
dists = np.sqrt((x - x[:,np.newaxis])**2 + (y - y[:,np.newaxis])**2)
# Test boolean array of persons IDs that changed locations
p_id = x > 0.5 # Just a dummy condition
x[p_id] = np.random.random(p_id.sum()) # Updated test x-coordinates
x[p_id] = np.random.random(p_id.sum()) # Updated test y-coordinates
dists_updated = np.sqrt((x - x[p_id,np.newaxis])**2 +
(y - y[p_id,np.newaxis])**2)
# Update distance matrix
dists[p_id] = dists_updated
dists[:,p_id] = dists_updated.T
推荐阅读
- javascript - 如何将查询字符串与 json 数据匹配?
- linux - 如何设置 OpenMP 以使用整个超线程进行并行处理?
- c# - 使用 Entity Framework Core 和 TempData 搜索 DateTime
- hive - 缺少 Hive 复杂列注释
- ios - 将 Whatsapp 图片发送给 ios 中的特定联系人
- rust - 解决递归类型绑定的不同策略是什么?
- wpf - 从 app.xaml 绑定到 MainWindowViewModel 属性
- r - R: make 2 subset vectors so that values are different index-wise
- python - 如何使用 pyTelegramBotAPI 将此数据保存到 txt
- python-3.x - 属性错误 Django 2.2.5