【问题标题】:Python convolution with histogram and Gaussian直方图和高斯的 Python 卷积
【发布时间】:2021-10-15 16:32:51
【问题描述】:

我有一个显示为直方图的模拟信号。我想使用具有特定宽度的高斯卷积来模拟实际测量信号,因为在实际实验中,检测器在测量通道中具有一定的不确定性。

我尝试使用np.convolvescipy.signal.convolve 进行卷积,但似乎无法正确过滤。不仅预期的形状是关闭的,这将是直方图和 x 轴的轻微涂抹版本,例如能量刻度也关闭了。

我尝试将宽度为 20 keV 的高斯定义为:

gauss = np.random.normal(0, 20000, len(coincidence['esum']))
hist_gauss = plt.hist(gauss, bins=100)[0]

其中len(coincidence['esum']) 是我的coincidencedataframe 列的长度。我使用的此列:

counts = plt.hist(coincidence['esum'], bins=100)[0]

除了生成合适的高斯的这种方法之外,我尝试了scipy.signal.gaussian(50, 30000),它不幸地生成了 抛物线外观 曲线并且没有表现出特征尾部。

我尝试使用两种高斯方法同时使用coincidence['esum']counts 进行卷积。请注意,根据Finding the convolution of two histograms 对标准示例进行简单卷积时,它可以正常工作。

有人知道如何在 python 中进行这样的卷积吗?我将用于直方图的coincidende['esum'] 列导出到了一个pastebin,以防有人感兴趣并希望使用特定数据https://pastebin.com/WFiSBFa6 重新创建它。

【问题讨论】:

    标签: python numpy scipy signal-processing convolution


    【解决方案1】:

    您可能知道,对具有相同 bin 大小的两个直方图进行卷积将得出将其中一个样本的每个元素与另一个样本的每个元素相加的结果的直方图。

    我看不出你在做什么。您似乎没有做的一件重要事情是确保直方图的 bin 具有相同的宽度,并且您必须注意第二个 bin 边缘的位置。

    在我们的代码中

    def hist_of_addition(A, B, bins=10, plot=False):
        A_heights, A_edges = np.histogram(A, bins=bins)
        # make sure the histogram is equally spaced
        assert(np.allclose(np.diff(A_edges), A_edges[1] - A_edges[0]))
        # make sure to use the same interval
        step = A_edges[1] - A_edges[0]
        
        # specify parameters to make sure the histogram of B will
        # have the same bin size as the histogram of A
        nBbin = int(np.ceil((np.max(B) - np.min(B))/step))
        left = np.min(B)
        B_heights, B_edges = np.histogram(B, range=(left, left + step * nBbin), bins=nBbin)
        
        # check that the bins for the second histogram matches the first
        assert(np.allclose(np.diff(B_edges), step))
        
        C_heights = np.convolve(A_heights, B_heights)
        C_edges = B_edges[0] + A_edges[0] + np.arange(0, len(C_heights) + 1) * step
        
        if plot:
            plt.figure(figsize=(12, 4))
            plt.subplot(131)
            plt.bar(A_edges[:-1], A_heights, step)
            plt.title('A')
            plt.subplot(132)
            plt.bar(B_edges[:-1], B_heights, step)
            plt.title('B')
            plt.subplot(133)
            plt.bar(C_edges[:-1], C_heights, step)
            plt.title('A+B')
        return C_edges, C_heights
    

    然后

    A = -np.cos(np.random.rand(10**6))
    B = np.random.normal(1.5, 0.025, 10**5)
    hist_of_addition(A, B, bins=100, plot=True);
    

    给予

    【讨论】:

    • 嘿@Bob,非常感谢您的回答!确保等距的 bin 和相同的步长间隔:使用 np.hist() 的标准使用是否是多余的?是否有一些边缘情况不会这样做。我认为默认值总是会解决这个问题。我关于noise 变量的第二个问题:你是如何定义它的,它在那里有什么用?另外:你是对的,可能没有正确分类我的历史是我的主要问题,尽管我尝试将它简单地设置为我的高斯和数据的分类,让我们在 plt.hist() 中说bins=60
    • np.histogramplt.hist 将自动选择步骤,以便它适合给定数量的 bin 中的所有数据,如果已修复,则没有理由返回边缘。
    • 噪音有一个错误,当我将它复制到函数中给你时,我将噪音重命名为B,我忘记了一些实例。
    • 好的,非常感谢您的解释和帮助,您实现它的方式正是我认为它应该工作的方式。我现在唯一的问题是信号幅度为 1,例如在scipy.signal.windows.gaussian 中,这样计数就不会像现在那样相乘。在“np.random.normal”中设置density=True 只会将积分设置为1。并且喂入 windows.gaussian 不起作用,因为它已经被自己装箱了
    • 保持计数并除以 len(B)。
    猜你喜欢
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 2016-07-05
    • 2021-08-11
    相关资源
    最近更新 更多