You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Numpy高效实现同形状ndarray间的元组计数?

用Numpy高效统计多数组同索引元组的出现次数

核心问题说明

你遇到的distribution[img, avg] += 1失效问题,本质是Numpy处理重复索引时,只会对每个唯一索引执行一次累加操作,不会自动统计重复出现的次数。下面提供两种优雅的Numpy原生解决方案:


方案1:np.bincount(最高效简洁)

将两个数组的索引组合成唯一整数编码,通过bincount统计频次后重塑为目标形状:

import numpy as np
from torch.nn.functional import avgpool2d

img = np.random.randint(0, 2, (64, 64))
avg = avgpool2d(img, kernel_size=3, padding=1).numpy() * 9
avg = avg.astype(np.int32)

# 把(i,j)二维索引编码为一维整数:i * 9 + j
encoded = img.flat * 9 + avg.flat
# 统计每个编码的出现次数,minlength确保覆盖所有可能的编码值
counts = np.bincount(encoded, minlength=18)
# 重塑为(2,9)的分布矩阵
distribution = counts.reshape(2, 9)

bincount是Numpy中统计整数频次的最优方法,时间复杂度O(n),完全规避循环。


方案2:np.unique结合return_counts

直接提取所有唯一的(i,j)元组并获取对应频次,再填充到结果数组:

import numpy as np
from torch.nn.functional import avgpool2d

img = np.random.randint(0, 2, (64, 64))
avg = avgpool2d(img, kernel_size=3, padding=1).numpy() * 9
avg = avg.astype(np.int32)

# 将两个数组的扁平化结果堆叠为N×2的元组矩阵
pairs = np.stack([img.flat, avg.flat], axis=1)
# 获取唯一元组及对应出现次数
unique_pairs, counts = np.unique(pairs, axis=0, return_counts=True)
# 初始化分布矩阵并赋值
distribution = np.zeros((2, 9), dtype=np.int32)
distribution[unique_pairs[:, 0], unique_pairs[:, 1]] = counts

这种方法更直观,适合需要查看所有唯一元组的场景,性能略逊于bincount但足以应对绝大多数需求。


扩展:N元组的通用统计方法

针对N个数组(如arr1, arr2, arr3)的场景,可采用两种通用思路:

  • 编码法:计算每个元组的唯一整数编码,例如encoded = arr1.flat * (size2*size3) + arr2.flat * size3 + arr3.flat,再用bincount统计。
  • 堆叠法:通过np.stack([arr1, arr2, arr3], axis=-1).reshape(-1, N)将所有元组转为二维数组,再用np.unique(..., axis=0, return_counts=True)统计。

内容的提问来源于stack exchange,提问作者illus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 11:47:26