如何计算落入区间的数据点数量

3 投票
3 回答
19701 浏览
提问于 2025-04-18 14:29

我已经设置好了我的数据区间(也就是“箱子”),现在我想知道怎么在某个数据点落在特定区间时,把这个区间的计数加一。简单来说,就是统计每个区间里有多少个数据点,这样我在画图的时候就可以用这个数字作为“频率”。

我的区间范围是这样设置的:

 bins = [(i*bin_width, (i+1)*bin_width) for i in range(num_bins)]

而我的数据大概是这样的:

2.55619101399
2.55619101399
2.55619101399
3.615
4.42745271008
2.55619101399
2.55619101399
2.55619101399
4.42745271008
3.615
2.55619101399
4.42745271008
5.71581687075
5.71581687075
3.615
2.55619101399
2.55619101399
2.55619101399
2.55619101399
2.55619101399

3 个回答

0

在编程中,有时候我们会遇到一些问题,比如代码运行不正常或者出现错误。这时候,我们可以去一些技术论坛,比如StackOverflow,寻求帮助。在这些论坛上,很多人会分享他们的经验和解决方案。

当你在这些论坛上提问时,记得把你的问题描述清楚,包括你遇到的具体情况和你尝试过的解决办法。这样,其他人才能更好地理解你的问题,并给出有效的建议。

另外,看到别人提问时,也可以学习到很多知识。很多时候,别人遇到的问题和你是相似的,解决方案也可能对你有帮助。

总之,技术论坛是一个很好的学习和交流的地方,利用好这些资源,可以帮助你更快地解决问题,提升自己的编程能力。

from collections import Counter

frequency_data = Counter()

    for d in data:
        new_bins = bins
        median = len(new_bins)/2
        while not new_bins[median][0] < d < new_bins[median][1]:
            if d < new_bins[median][0]:
                new_bins = new_bins[:median]
            elif d > new_bins[median][1]:
                new_bins = new_bins[median:]
            median = len(new_bins)/2
        frequency_data[new_bins[median]] += 1
6

既然你在使用NumPy,那么你(a)就不应该试着创建列表并循环处理它们,而是应该使用数组;(b)你应该看看你想做的事情是否已经有现成的功能(或者在SciPy、Pandas或其他基于NumPy的库中可以找到),因为很多时候都是有的。

而且,numpy.histogram正是你需要的工具。

它需要的是总宽度,而不是每个区间的宽度,不过除此之外,你只需把已有的数值放进去,就能得到你想要的结果:

hist, edges = np.histogram(
    data_points,
    bins=num_bins,
    range=(0, bin_width*num_bins),
    density=False)

hist数组会包含每个区间的计数(就像我之前回答中的bin_counts),这正是你想要后续处理和最终绘图的数据。

edges这个部分你可能需要,也可能不需要。它包含的信息和你最初问题中的bins是一样的,只是格式不同——它不是[(0, .1), (.1, .2), (.2, .3)],而是[0, .1, .2, .3]

3

首先,你的每个 bins 其实就是一对数字,表示这个区间的开始和结束值,所以你不能往里面添加东西。你可以把每个 bin 改成一个列表,比如 [start, stop, 0],而不是用元组 (start, stop),或者更好的是,使用一个对象。另外,你也可以保持一个单独的 bin_counts 列表,和 bins 列表并行使用,比如在需要的时候把它们结合起来。

接下来,如果每个 bin 的范围是从 i * bin_width(i+1) * bin_width,那么你怎么从数据值中得到 i 呢?这很简单:乘法的反操作是除法,所以你只需要 data_point // bin_width 就可以了。

所以:

bin_counts = [0 for bin in bins]
for data_point in data_points:
    bin_number = data_point // bin_width
    bin_counts[bin_number] += 1

这里展示了另一种选择,因为我觉得你在评论中提到过这个:

bins = [[i*bin_width, (i+1)*bin_width, 0] for i in range(num_bins)]
for data_point in data_points:
    bin_number = data_point // bin_width
    bins[bin_number][2] += 1

在这里,每个 bin 是一个列表 [start, stop, count],而不是有一个 (start, stop) 的列表和一个单独的 count 值的列表。

撰写回答