Python中如何按均值条件筛选网格单元过滤空单元绘制直方图
问题核心
你当前需要实现的逻辑是:基于一一对应的x、y坐标和v值数组,完成x-y平面网格划分后,将v值分配到对应网格单元,计算每个单元的v值均值,最终仅对均值大于2的非空单元绘制单元内原始v值的分布直方图,过滤空单元生成的无效空白直方图。
原代码问题点
- 无前置校验逻辑:遍历所有网格单元时直接创建画布绘图,既不判断单元是否为空,也不提前判断单元均值是否满足阈值要求,导致空单元、均值不达标单元都会生成画布
- 判空方式错误:numpy数组不能直接用
!=[]的列表判空逻辑做判断,会触发类型报错,numpy空数组需要通过.size属性判断元素总数是否为0 - 绘图逻辑错误:
plt.hist(this[(mean_pix>2)])中mean_pix是单个单元的均值标量,不是和this等长的布尔数组,用标量布尔值索引数组会返回空结果,直接生成空白直方图 - 存在冗余计算:两次执行网格单元的v值归集逻辑,没有必要
修正后代码
import numpy as np import matplotlib.pyplot as plt x = np.array([11,12,12,13,21,14]) y = np.array([28,5,15,16,12,4]) v = np.array([10,5,2,10,6,7]) # 坐标映射到对应网格 x = x // 4 y = y // 4 grid_size = 10 cells = [[[] for _ in range(grid_size)] for _ in range(grid_size)] # 一次性完成所有网格的v值归集,无需重复计算 for y_idx in range(grid_size): for x_idx in range(grid_size): cells[y_idx][x_idx] = v[(y == y_idx) & (x == x_idx)] # 遍历网格,仅对满足条件的单元绘图 for y_idx in range(grid_size): for x_idx in range(grid_size): current_v = cells[y_idx][x_idx] # 过滤空单元 if current_v.size == 0: continue # 计算单元均值,过滤均值不满足阈值的单元 cell_mean = np.mean(current_v) if cell_mean <= 2: continue # 校验通过后再创建画布绘图 fig, ax = plt.subplots() plt.hist(current_v, edgecolor='black') plt.title(f'网格单元(x={x_idx}, y={y_idx}) v值均值:{cell_mean:.2f}') plt.xlabel('v值') plt.ylabel('频次') plt.show()
逻辑说明
- 把网格v值归集逻辑提前,只执行一次,减少重复计算
- 增加两层前置判断:先过滤空单元,再判断单元均值是否达标,只有两个条件都满足时才创建绘图对象,从根源上避免空白无效直方图
- 修正了numpy数组的判空方式,通过
.size属性获取数组元素总数,为0即为空数组,不会触发类型报错 - 修正了原有的错误索引逻辑,直接对满足条件的单元内全部v值绘制直方图,符合需求
- 给直方图增加了标题和坐标轴标注,方便区分不同网格的统计结果
内容的提问来源于stack exchange,提问作者Jerome
相关产品推荐
相关产品推荐

