如何统计不平衡4D NumPy数组中各类元素的数量?
咱先理清楚你遇到的核心问题:你的mask标签是浮点型的,没法直接用常规的整数类别统计方法,这其实分两种常见场景,我给你逐个拆解解决:
场景1:标签本应为整数0-3,只是浮点存储有微小误差
如果你的数组里的数值本质上就是0、1、2、3这四个整数,只是因为数据转换或存储变成了float32格式(比如存成了0.0、1.0,但可能带着0.00001或2.999999这类浮点偏差),那咱们先把这些值修正回整数,再统计就没问题了:
import numpy as np # 先去掉最后一维(因为是1,完全不影响数据内容) masks_2d = masks.squeeze(axis=-1) # 处理后形状变成(1513, 256, 256) # 四舍五入到最近整数,修正浮点误差 y_integers = np.round(masks_2d).astype(np.int32) # 统计每个类别的像素数量 class_counts = np.bincount(y_integers.flatten()) print("类别0到3的像素数分别是:", class_counts) # 接下来计算类别权重(用你原来的方法就行) from sklearn.utils.class_weight import compute_class_weight class_weights = compute_class_weight('balanced', classes=np.arange(4), y=y_integers.flatten()) d_class_weights = dict(enumerate(class_weights))
⚠️ 注意:如果你的数组里出现1.6、2.3这种明显偏离整数的值,那说明你的标签不是硬整数标签,得看下面的场景。
场景2:浮点值是模糊/软标签(像素同时属于多个类别)
如果每个像素的浮点值是连续的(比如0.5、1.2),代表这个像素同时属于多个类别(比如1.2意味着80%属于类别1,20%属于类别2),那咱们得按类别权重占比来统计每个类别的总贡献:
import numpy as np masks_2d = masks.squeeze(axis=-1) flat_masks = masks_2d.flatten() # 初始化四个类别的计数容器 class_counts = np.zeros(4, dtype=np.float32) for x in flat_masks: # 先把值限制在0-3范围内,避免异常值干扰 x_clamped = np.clip(x, 0.0, 3.0) k = int(np.floor(x_clamped)) if k == 3: # 如果值接近或等于3,全部贡献给类别3 class_counts[3] += 1.0 else: # 把当前值拆给相邻的两个类别,按比例分配权重 weight_to_k1 = x_clamped - k weight_to_k = 1.0 - weight_to_k1 class_counts[k] += weight_to_k class_counts[k+1] += weight_to_k1 print("每个类别的加权像素数:", class_counts) # 计算类别权重的话,用这些加权计数就行 total_pixels = class_counts.sum() class_weights = total_pixels / (4 * class_counts) d_class_weights = dict(enumerate(class_weights))
为啥你原来的代码没效果?
你用了np.argmax(masks, axis=1),但你的数组形状是(1513,256,256,1),axis=1对应的是图像的高度维度,这完全不对啊!argmax是用来处理one-hot编码的数组的(比如形状是(样本数, 高, 宽, 4),每个像素是4维的概率向量),但你的数组最后一维只有1个元素,所以argmax在这里根本起不到提取类别的作用。
内容的提问来源于stack exchange,提问作者Mahyar
相关产品推荐
相关产品推荐

