Python 如何有效地更改矩阵/嵌套列表中的条目?

Python 如何有效地更改矩阵/嵌套列表中的条目?,python,multidimensional-array,nested-lists,processing-efficiency,Python,Multidimensional Array,Nested Lists,Processing Efficiency,对于蒙特卡罗模拟,我有500个Person实例,每个实例都有一个位置(笛卡尔坐标)作为属性。在整个模拟过程中,我需要多次访问两个人对之间的距离。我已经定义了一个函数来计算两个人对之间的(笛卡尔)距离(为了简单起见,我们称这个函数为“距离(loc1,loc2)”。 我对提高脚本的计算效率感兴趣。我采取的第一步是创建一个存储距离的对称矩阵,而不是每次需要时计算距离。现在我决定把它做成一个嵌套的numpy数组;我可以把它改成嵌套列表或者其他一些东西,如果它能让事情变得更简单的话。(我用这本书的改编版本

对于蒙特卡罗模拟,我有500个Person实例,每个实例都有一个位置(笛卡尔坐标)作为属性。在整个模拟过程中,我需要多次访问两个人对之间的距离。我已经定义了一个函数来计算两个人对之间的(笛卡尔)距离(为了简单起见,我们称这个函数为“距离(loc1,loc2)”。 我对提高脚本的计算效率感兴趣。我采取的第一步是创建一个存储距离的对称矩阵,而不是每次需要时计算距离。现在我决定把它做成一个嵌套的numpy数组;我可以把它改成嵌套列表或者其他一些东西,如果它能让事情变得更简单的话。(我用这本书的改编版本制作了矩阵:) 距离矩阵如下所示:

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\u 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

非常感谢你的回答。然而,我存储了巨大的圆距离(因此您的距离公式不准确)。但是,使用列表理解来更新行和列非常有效,因此非常感谢您的回复