慕标琳琳
有一个使用np.put, 及其'clip'选项的解决方案。它只需要一点技巧,因为该函数需要扁平矩阵中的索引;幸运的是,该功能np.ravel_multi_index完成了这项工作:import itertoolsimport numpy as npx, y, z = 2, 0, 4positions_matrix = np.zeros((100,100,100))indices = np.array( list( itertools.product( (x-1, x, x+1), (y-1, y, y+1), (z-1, z, z+1)) ))flat_indices = np.ravel_multi_index(indices.T, positions_matrix.shape, mode='clip')positions_matrix.put(flat_indices, 1+positions_matrix.take(flat_indices))# positions_matrix[2,1,4] is now 1.0这个解决方案的好处是您可以使用其他模式,例如'wrap'(如果您的代理住在甜甜圈上;-) 或周期性空间)。我将解释它如何在较小的 2D 矩阵上工作:import itertoolsimport numpy as nppositions_matrix = np.zeros((8,8))ones = np.ones((3,3))x, y = 0, 4indices = np.array( list( itertools.product( (x-1, x, x+1), (y-1, y, y+1) )))# array([[-1, 3],# [-1, 4],# [-1, 5],# [ 0, 3],# [ 0, 4],# [ 0, 5],# [ 1, 3],# [ 1, 4],# [ 1, 5]])flat_indices = np.ravel_multi_index(indices.T, positions_matrix.shape, mode='clip')# array([ 3, 4, 5, 3, 4, 5, 11, 12, 13])positions_matrix.put(flat_indices, ones, mode='clip')# positions_matrix is now:# array([[0., 0., 0., 1., 1., 1., 0., 0.],# [0., 0., 0., 1., 1., 1., 0., 0.],# [0., 0., 0., 0., 0., 0., 0., 0.],# [ ...顺便说一句,在这种情况下mode='clip'是多余的put。好吧,我只是作弊put做作业。+=1需要take和put:_positions_matrix.put(flat_indices, ones.flat + positions_matrix.take(flat_indices))# notice that ones has to be flattened, or alternatively the result of take could be reshaped (3,3)# positions_matrix is now: # array([[0., 0., 0., 2., 2., 2., 0., 0.],# [0., 0., 0., 2., 2., 2., 0., 0.],# [0., 0., 0., 0., 0., 0., 0., 0.],# [ ...与其他解决方案相比,此解决方案有一个重要区别:ones矩阵始终为 (3,3),这可能是优势,也可能不是优势。诀窍就在这个 flat_indices 列表中,它有重复的条目(剪辑的结果)。因此,如果您在最大索引处添加非常数子矩阵,则可能需要采取一些预防措施:x, y = 1, 7values = 1 + np.arange(9)indices = np.array( list( itertools.product( (x-1, x, x+1), (y-1, y, y+1) )))flat_indices = np.ravel_multi_index(indices.T, positions_matrix.shape, mode='clip')positions_matrix.put(flat_indices, values, mode='clip')# positions_matrix is now:# array([[0., 0., 0., 2., 2., 2., 1., 3.],# [0., 0., 0., 2., 2., 2., 4., 6.],# [0., 0., 0., 0., 0., 0., 7., 9.],...您可能期望最后一列是 2 5 8。目前,您可以处理flat_indices,例如通过放置-1越界位置。但是,如果np.put接受非平面索引,或者如果有一个 clip ,这一切都会更容易mode='ignore'。