有没有快速的方法来合并两个具有不同 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
其实我不知道x
和y
,只知道a
和b
。
但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/