处理2D列表python的周围环境

处理2D列表python的周围环境,python,multidimensional-array,Python,Multidimensional Array,我想浏览一个二维的数字列表,然后对每个元素及其周围的元素进行一些计算。当一个数字在“墙”上时,它应该自己计算。 例如 我考虑在双for循环中使用一些if语句来处理角落和墙上的数字: for i in range(len(list1)): for j in range(len(list1[i])): if j == 0 : #elements at the left wall #do something elif i == 0 and j == 0

我想浏览一个二维的数字列表,然后对每个元素及其周围的元素进行一些计算。当一个数字在“墙”上时,它应该自己计算。 例如

我考虑在双for循环中使用一些if语句来处理角落和墙上的数字:

for i in range(len(list1)):
    for j in range(len(list1[i])):

      if j == 0 : #elements at the left wall
        #do something
      elif i == 0 and j == 0: #element in the top left corner

      ...
我的第一个问题是:

有没有更聪明的方法来处理二维列表的环境? 是否有一个函数可以执行以下操作:

if Index out of range:
  do something (not throwing and error message but calculate like above)
import numpy as np
from scipy import signal

data = np.array([[1,2,3],
                 [4,5,6],
                 [7,8,9]])
kernel = np.array([[0, 1, 0],
                   [1, 1, 1],
                   [0, 1, 0]])
result = signal.convolve2d(data, kernel, boundary='symm', mode='same')
print(result)

>>> array([[ 9, 13, 17],
           [21, 25, 29],
           [33, 37, 41]])
我的第二个问题是:

我想首先计算所有值,然后立即更新矩阵的值。 我想把新值放在第一个列表的副本中

list2 = list1[:] #copy using slice method
但list2似乎总是与list1相同,当for循环到达第二个元素时,它已经用新值替换了第一个元素

谢谢你的帮助

更新:

虽然运算是卷积运算,但在这种情况下,使用简单的矢量化加法可以更快地计算,如中所述


您所描述的是二维卷积运算,是信号处理中经常出现的运算。典型的应用是图像过滤。这是一个很好的解释,但它基本上归结为你想做什么

在SciPy中有该操作的NumPy实现。卷积的智能实现将比直接的基于循环的方法快得多,所以通常值得使用现有的方法。对于您的情况,您可以执行以下操作:

if Index out of range:
  do something (not throwing and error message but calculate like above)
import numpy as np
from scipy import signal

data = np.array([[1,2,3],
                 [4,5,6],
                 [7,8,9]])
kernel = np.array([[0, 1, 0],
                   [1, 1, 1],
                   [0, 1, 0]])
result = signal.convolve2d(data, kernel, boundary='symm', mode='same')
print(result)

>>> array([[ 9, 13, 17],
           [21, 25, 29],
           [33, 37, 41]])

我已经意识到,对于您非常简单的情况(一个权重为1或0的小内核),您也可以手动执行该操作,仅以矢量化的方式:

import numpy as np

data = np.array([[1,2,3],
                 [4,5,6],
                 [7,8,9]])
result = np.zeros_like(data)
result += data
result[1:] += data[:-1]
result[:-1] += data[1:]
result[:, 1:] += data[:, :-1]
result[:, :-1] += data[:, 1:]
result[0] += data[0]
result[-1] += data[-1]
result[:, 0] += data[:, 0]
result[:, -1] += data[:, -1]
print(result)

>>> array([[ 9, 13, 17],
           [21, 25, 29],
           [33, 37, 41]])
我认为这在理论上应该更快,因为您只是在做加法,尽管它有更多的Python-C行程(也许可以节省一些行程),因此它最终可能取决于矩阵的大小

更新:

经过两次快速测试后,在我的机器中输入30x30或更大的尺寸时,这种方法确实更快,因此除非您的输入非常小(在这种情况下,性能无论如何都不重要),否则您应该更喜欢这种方法