python - 合并不同范围的直方图

标签 python numpy merge histogram

有没有快速的方法来合并两个具有不同 bin 范围和 bin 编号的 numpy 直方图?

例如:

x = [1,2,2,3]
y = [4,5,5,6]

a = np.histogram(x, bins=10)  
#  a[0] = [1, 0, 0, 0, 0, 2, 0, 0, 0, 1]
#  a[1] = [ 1. ,  1.2,  1.4,  1.6,  1.8,  2. ,  2.2,  2.4,  2.6,  2.8,  3. ]

b = np.histogram(y, bins=5)
#  b[0] = [1, 0, 2, 0, 1]
#  b[1] = [ 4. ,  4.4,  4.8,  5.2,  5.6,  6. ]

现在我想要一些像这样的功能:

def merge(a, b):
    # some actions here #
    return merged_a_b_values, merged_a_b_bins

其实我不知道xy,只知道ab。 但merge(a, b)的结果必须等于np.histogram(x+y, bins=10):

m = merge(a, b)
#  m[0] = [1, 0, 2, 0, 1, 0, 1, 0, 2, 1]
#  m[1] = [ 1. ,  1.5,  2. ,  2.5,  3. ,  3.5,  4. ,  4.5,  5. ,  5.5,  6. ] 

最佳答案

我实际上会在 dangom 的答案中添加评论,但我缺乏所需的声誉。 我对你的例子有点困惑。如果我没记错的话,您正在绘制直方图箱的直方图。应该是这样,对吧?

plt.figure()
plt.plot(a[1][:-1], a[0], marker='.', label='a')
plt.plot(b[1][:-1], b[0], marker='.', label='b')
plt.plot(c[1][:-1], c[0], marker='.', label='c')
plt.legend()
plt.show()

还有关于组合直方图的建议的注释。您当然是对的,没有唯一的解决方案,因为您根本不知道样本会位于您用于组合的更精细的网格中。当有两个柱宽显着不同的直方图时,建议的合并函数可能会导致稀疏且人工的直方图。

我尝试通过插值组合直方图(假设计数箱内的样本均匀分布在原始箱中 - 这当然也只是一个假设)。 然而,这会导致看起来更自然的结果,至少对于从我通常遇到的分布中采样的数据来说是这样。

import numpy as np
def merge_hist(a, b):

    edgesa = a[1]
    edgesb = b[1]
    da = edgesa[1]-edgesa[0]
    db = edgesb[1]-edgesb[0]
    dint = np.min([da, db])

    min = np.min(np.hstack([edgesa, edgesb]))
    max = np.max(np.hstack([edgesa, edgesb]))
    edgesc = np.arange(min, max, dint)

    def interpolate_hist(edgesint, edges, hist):
        cumhist = np.hstack([0, np.cumsum(hist)])
        cumhistint = np.interp(edgesint, edges, cumhist)
        histint = np.diff(cumhistint)
        return histint

    histaint = interpolate_hist(edgesc, edgesa, a[0])
    histbint = interpolate_hist(edgesc, edgesb, b[0])

    c = histaint + histbint
    return c, edgesc

两个高斯分布的示例:

import numpy as np
a = 5 + 1*np.random.randn(100)
b = 10 + 2*np.random.randn(100)
hista, edgesa = np.histogram(a, bins=10)
histb, edgesb = np.histogram(b, bins=5)

histc, edgesc = merge_hist([hista, edgesa], [histb, edgesb])

plt.figure()
width = edgesa[1]-edgesa[0]
plt.bar(edgesa[:-1], hista, width=width)
width = edgesb[1]-edgesb[0]
plt.bar(edgesb[:-1], histb, width=width)
plt.figure()
width = edgesc[1]-edgesc[0]
plt.bar(edgesc[:-1], histc, width=width)

plt.show()

但是,我不是统计学家,所以请让我知道建议的方法是否可行。

关于python - 合并不同范围的直方图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47085662/

相关文章:

python - 根据纬度和经度过滤数据 - Numpy

MySQL 合并 2 个具有相同 Id 值的表

r - 如何将特定数据从一个数据帧添加到另一个更大的数据帧?

python - 如何减少线程 python 代码的内存使用?

c++ - 用 Python+ctypes、segfault 包装 C++ 动态数组

python - 如何以彩色显示 tiff 文件?

python - 如何在线性方程组中找到唯一的非简并方程

Python 模块导入名称错误

python - 从 .ui 自动完成

ruby-on-rails - rails/ruby 合并两个具有相同键、不同值的散列