合并两个具有不同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

实际上,我没有xyab只知道。
但是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. ]

最佳答案

合并两个不同直方图的问题没有唯一的解决方案。我在这里提出了一个简单而快速的解决方案,基于两个必要的设计假设,以处理装箱序列固有的信息丢失:
恢复的值由它们所属的bin的开头表示。
合并应保持最高的bin分辨率,以避免进一步丢失信息,并应完全包含子直方图的间隔。
代码如下:

  import numpy as np

  def merge(a, b):

      def extract_vals(hist):
          # Recover values based on assumption 1.
          values = [[y]*x for x, y in zip(hist[0], hist[1])]
          # Return flattened list.
          return [z for s in values for z in s]

      def extract_bin_resolution(hist):
          return hist[1][1] - hist[1][0]

      def generate_num_bins(minval, maxval, bin_resolution):
          # Generate number of bins necessary to satisfy assumption 2
          return int(np.ceil((maxval - minval) / bin_resolution))

      vals = extract_vals(a) + extract_vals(b)
      bin_resolution = min(map(extract_bin_resolution, [a, b]))
      num_bins = generate_num_bins(min(vals), max(vals), bin_resolution)

      return np.histogram(vals, bins=num_bins)

下面是示例代码:
import matplotlib.pyplot as plt

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. ]

# Merge and plot results
c = merge(a, b)

c_num_bins = c[1].size - 1

plt.hist(a[0], bins=5, label='a')
plt.hist(b[0], bins=10, label='b')
plt.hist(c[0], bins=c_num_bins, label='c')
plt.legend()

plt.show()

10-06 13:54
查看更多