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

Python仅用基础NumPy实现二维联合直方图替代histogram2d

NumPy手动实现二维联合直方图方案

要完全替代np.histogram2d得到一致输出,需要严格对齐NumPy官方的分箱、计数规则,全程仅使用NumPy基础函数即可实现,不需要依赖其他直方图相关内置接口。

核心实现逻辑

  • 对齐官方参数规则:如果bins传入单个整数,x、y两个维度使用相同的分箱数量
  • 等宽分箱边界生成:用np.linspace从样本最小值到最大值生成箱数+1个边界点,保证每个分箱宽度一致
  • 索引计算:通过偏移+除法+向下取整得到每个样本点所属的分箱索引,单独处理最大值点,将其归入最后一个分箱(官方规则为最后一个分箱是双闭区间,其余分箱左闭右开)
  • 向量化计数:用np.add.at完成无冲突的分箱计数,避免遍历循环,保证计数结果和官方函数完全一致

可直接替换的实现代码

import numpy as np

def manual_histogram2d(x, y, bins):
    # 处理bins参数:单整数则两维度分箱数一致
    if np.isscalar(bins):
        x_bin_num = y_bin_num = bins
    else:
        x_bin_num, y_bin_num = bins
    
    # 生成和np.histogram2d完全一致的分箱边界
    x_edges = np.linspace(x.min(), x.max(), x_bin_num + 1)
    y_edges = np.linspace(y.min(), y.max(), y_bin_num + 1)

    # 计算x维度分箱索引
    x_width = x_edges[1] - x_edges[0]
    x_idx = np.floor((x - x_edges[0]) / x_width).astype(int)
    x_idx[x_idx == x_bin_num] = x_bin_num - 1  # 最大值归入最后一箱

    # 计算y维度分箱索引
    y_width = y_edges[1] - y_edges[0]
    y_idx = np.floor((y - y_edges[0]) / y_width).astype(int)
    y_idx[y_idx == y_bin_num] = y_bin_num - 1  # 最大值归入最后一箱

    # 初始化计数矩阵并完成统计
    hist_2d = np.zeros((x_bin_num, y_bin_num), dtype=np.intp)
    np.add.at(hist_2d, (x_idx, y_idx), 1)

    return hist_2d, x_edges, y_edges

替换使用方法

将原代码中调用np.histogram2d的部分替换为自定义函数即可,后续绘图逻辑不需要做任何修改:

from matplotlib.pyplot import imread
import matplotlib.pyplot as plt

Img1 = imread('img1.jpg')
Img2 = imread('img2.jpg')
# 替换原np.histogram2d调用
hist_2d, x_edges, y_edges = manual_histogram2d(Img1.ravel(), Img2.ravel(), bins=bins)

plt.imshow(hist_2d.T, origin='lower')

你可以通过np.allclose对比手动实现和官方函数的三个返回值,结果会完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 20:39:16