仅使用for循环计算二进制矩阵行距离矩阵的技术求助
解决二进制矩阵行间汉明距离矩阵的For循环实现问题
我明白你现在卡在了用for循环计算二进制矩阵行之间的距离矩阵上,别担心,咱们一步步来解决这个问题——你要计算的其实是汉明距离:两个向量对应位置不同元素的个数,最终得到的对称矩阵里,(i,j)位置的值就是第i行和第j行的汉明距离。
先给你正确的两层For循环实现代码
首先确保你导入了numpy,然后按照下面的代码来写,就能得到你想要的结果:
import numpy as np # 你的输入二进制矩阵 binary_matrix = np.matrix([[0,0,0], [1,0,1], [1,1,1]]) n_rows = binary_matrix.shape[0] # 获取矩阵的行数,这里是3 # 初始化一个全零的结果矩阵,类型设为整数 distance_matrix = np.zeros((n_rows, n_rows), dtype=int) # 第一层循环:遍历每一行i for i in range(n_rows): # 把第i行转换成一维数组,避免matrix类型的维度问题 row_i = binary_matrix[i].A.flatten() # 第二层循环:遍历每一行j for j in range(n_rows): row_j = binary_matrix[j].A.flatten() # 计算两行不同元素的数量:先逐位置比较是否不等,再求和(True=1,False=0) diff_count = np.sum(row_i != row_j) # 赋值到结果矩阵的对应位置 distance_matrix[i, j] = diff_count print(distance_matrix)
运行这段代码后,你就能得到目标矩阵:
[[0 2 3] [2 0 1] [3 1 0]]
为什么你之前的遍历可能出错?
大概率是你在处理矩阵行的时候遇到了维度问题:np.matrix的行是二维的matrix对象,直接用来逐元素比较会有麻烦。用.A.flatten()可以把它转换成一维的numpy数组,这样就能顺利进行逐位置的不等判断了。
另外,用np.sum(row_i != row_j)比手动逐个判断累加更简洁,也不容易出现计数错误——布尔数组里的True会被当作1,False当作0,求和直接得到不同元素的总数。
优化版For循环(利用矩阵对称性减少计算)
因为距离矩阵是对称的(第i行和第j行的距离等于第j行和第i行的距离),而且对角线元素都是0(自己和自己的距离为0),我们可以优化循环,只计算上三角部分,减少一半的计算量:
import numpy as np binary_matrix = np.matrix([[0,0,0], [1,0,1], [1,1,1]]) n_rows = binary_matrix.shape[0] distance_matrix = np.zeros((n_rows, n_rows), dtype=int) for i in range(n_rows): row_i = binary_matrix[i].A.flatten() distance_matrix[i, i] = 0 # 对角线元素直接设为0 # 只遍历i之后的行j,避免重复计算 for j in range(i + 1, n_rows): row_j = binary_matrix[j].A.flatten() diff_count = np.sum(row_i != row_j) distance_matrix[i, j] = diff_count distance_matrix[j, i] = diff_count # 对称位置赋值 print(distance_matrix)
额外补充:非For循环的高效实现(可选)
虽然你要求用For循环,但还是提一句:如果后续不需要限制循环,用scipy的工具可以一行搞定:
from scipy.spatial.distance import cdist distance_matrix = cdist(binary_matrix, binary_matrix, metric='hamming') * binary_matrix.shape[1] distance_matrix = distance_matrix.astype(int)
这里的hamming距离返回的是不同元素的比例,乘以每行的长度就得到实际的个数,转换为整数后就是目标矩阵。
内容的提问来源于stack exchange,提问作者mdelas
相关产品推荐
相关产品推荐

