矩阵获取8邻域元素并存储至neighbourMatrix的问题排查与修正
字符矩阵邻域获取问题解决
问题背景
现有如下字符类型矩阵:
matrix = [ ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-'], ['-', '-', '-', '+', '-', '-', '-', '+', '-', '-', '-', '+', '-', '-', '+', '-', '-', '-', '-', '-'], ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-'], ['+', '+', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-'], ['-', '+', '-', '+', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-'], ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-'], ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '-', '+'], ['-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '-', '+'], ['+', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-'], ['-', '-', '+', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '+', '-'] ]
需要为每个单元格获取全部8个邻域元素,存储到neighbourMatrix中,但运行时出现如下报错:
ValueError: could not convert string to float: '-'
使用的函数代码如下:
def getNeighbours(matrix, neighbourMatrix): """this function will define and store all 8 neighboring cells in a new matrix""" for i in range(len(matrix)): # loop through rows and columns of matrix for j in range(len(matrix[0])): # if there is no "lower bound neighbour", jump to last row if i == 0: neighbourMatrix[i][j] = matrix[len(matrix) - 1][j - 1] neighbourMatrix[i][j + 1] = matrix[len(matrix) - 2][j] neighbourMatrix[i][j + 2] = matrix[len(matrix) - 2][j + 1] else: neighbourMatrix[i][j] = matrix[i - 1][j - 1] neighbourMatrix[i][j + 1] = matrix[i - 1][j] neighbourMatrix[i][j + 2] = matrix[i - 1][j + 1] # if there is no "lower bound neighbour", jump to last column if j == 0: neighbourMatrix[i][j] = matrix[i - 1][len(matrix[0]) - 2] neighbourMatrix[i][j + 3] = matrix[i][len(matrix[0]) - 2] neighbourMatrix[i][j + 5] = matrix[i + 1][len(matrix[0]) - 2] else: neighbourMatrix[i][j] = matrix[i - 1][j - 1] neighbourMatrix[i][j + 3] = matrix[i][j - 1] neighbourMatrix[i][j + 5] = matrix[i + 1][j - 1] # if there is no "upper bound neighbour", jump to first row if (i == len(matrix) - 1): neighbourMatrix[i][j + 5] = matrix[0][j - 1] neighbourMatrix[i][j + 6] = matrix[0][j] neighbourMatrix[i][j + 7] = matrix[0][j + 1] else: neighbourMatrix[i][j + 5] = matrix[i + 1][j - 1] neighbourMatrix[i][j + 6] = matrix[i + 1][j] neighbourMatrix[i][j + 7] = matrix[i + 1][j + 1] # if there is no "upper bound neighbour", jump to first column if (j == len(matrix[0]) - 1): neighbourMatrix[i][j + 2] = matrix[i - 1][0] neighbourMatrix[i][j + 4] = matrix[i][0] neighbourMatrix[i][j + 7] = matrix[i + 1][0] else: neighbourMatrix[i][j + 2] = matrix[i - 1][j + 1] neighbourMatrix[i][j + 4] = matrix[i][j + 1] neighbourMatrix[i][j + 7] = matrix[i + 1][j + 1] print(neighbourMatrix)
问题分析
1. 类型错误原因
报错是因为neighbourMatrix被初始化为数值类型容器(比如numpy的浮点型数组),但要存储字符类型的'-'或'+',类型不匹配导致转换失败。
2. 算法逻辑错误
- 结构设计错误:原代码试图将8个邻域元素分散存储在
neighbourMatrix的(i,j)、(i,j+1)等位置,这不仅会导致列索引越界(比如j为最后一列时j+1超出矩阵列长度),还不符合“每个单元格对应8个邻域元素”的需求,正确结构应为neighbourMatrix是与原矩阵同尺寸的二维数组,每个元素是存储8个邻域的列表。 - 重复赋值覆盖:多个
if-else块对同一个neighbourMatrix[i][j]赋值,后续赋值会覆盖之前的结果,逻辑完全混乱。 - 边界处理错误:边界判断时使用的索引计算错误(比如
i=0时取len(matrix)-2行,不是循环边界的正确处理),且未处理j-1为负数的情况,导致索引越界。
修正方案
修正思路
- 初始化
neighbourMatrix为列表嵌套列表的结构,每个子列表存储对应单元格的8个邻域元素。 - 使用模运算处理循环边界:当邻域索引超出矩阵范围时,自动绕到对面(比如第一行的上邻域为最后一行,最后一列的右邻域为第一列)。
- 定义8个邻域的偏移量,通过循环遍历所有邻域,避免重复代码。
修正后代码
def getNeighbours(matrix): """获取每个单元格的8个邻域元素,返回邻域矩阵""" rows = len(matrix) cols = len(matrix[0]) # 初始化邻域矩阵:每个位置是一个空列表,用于存储8个邻域元素 neighbourMatrix = [[[] for _ in range(cols)] for _ in range(rows)] # 定义8个邻域的行、列偏移量(按左上、中上、右上、左中、右中、左下、中下、右下顺序) offsets = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] for i in range(rows): for j in range(cols): for dr, dc in offsets: # 用模运算处理循环边界,避免索引越界 neighbor_row = (i + dr) % rows neighbor_col = (j + dc) % cols # 将邻域元素添加到对应位置的列表中 neighbourMatrix[i][j].append(matrix[neighbor_row][neighbor_col]) return neighbourMatrix # 使用示例 matrix = [ ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-'], ['-', '-', '-', '+', '-', '-', '-', '+', '-', '-', '-', '+', '-', '-', '+', '-', '-', '-', '-', '-'], ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-'], ['+', '+', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-'], ['-', '+', '-', '+', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-'], ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-'], ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '-', '+'], ['-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '-', '+'], ['+', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-'], ['-', '-', '+', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '+', '-'] ] neighbourMatrix = getNeighbours(matrix) # 打印第一个单元格的邻域示例 print("第一个单元格(0,0)的8个邻域:", neighbourMatrix[0][0])
代码说明
offsets定义了8个邻域相对于当前单元格的位置偏移,覆盖所有方向。(i + dr) % rows和(j + dc) % cols通过模运算实现循环边界:比如i=0时,dr=-1会得到(0-1)%10=9,即最后一行,实现上边界循环到最后一行。neighbourMatrix初始化为列表嵌套列表,每个元素是空列表,确保可以存储字符类型元素,避免类型转换错误。
内容的提问来源于stack exchange,提问作者Andrew Marra
相关产品推荐
相关产品推荐

