python: 有没有频率函数?

2 投票
4 回答
6326 浏览
提问于 2025-04-16 02:15

在Excel中,有一个叫做频率函数的功能:

Excel的频率函数是一个很有用的功能,它可以分析一系列的数值,并把这些数值总结成几个指定的范围。比如说,孩子们的身高可以分成四个类别:[低于150厘米];[151 - 160厘米];[161 - 170厘米];[高于170厘米]。

你想了解更多吗?

《Excel 2003公式》作者:John Walkenbach(附光盘)

FREQUENCY()是一个比较特别的数组函数,它的工作方式和大多数普通函数不一样。你不能简单地把它输入到一个单元格里,甚至用Excel的函数向导也无法正确输入。

需要注意的是,这个函数并不是用来把数值分析成类别的,比如把家庭开支分成燃气、电费、水费、税费等。如果想进行这种分析,可能需要使用高级筛选功能。

频率函数有两个参数——第一个是包含要分析的数值的单元格范围;第二个是包含每个组的上限值的单元格范围。例如:=FREQUENCY(A3:A120, B6:B10)

第二个参数(组的上限)会排除任何超过最高类别或范围的数值。这个函数允许你考虑到这一点,并将分析范围扩展到一个额外的类别,包含所有超过指定上限的数值。

http://www.meadinkent.co.uk/xlfreq.htm

在Python中有没有类似的功能?

4 个回答

1

根据我参考的页面 http://www.meadinkent.co.uk/xlfreq.htm 上所说的,我写了一个函数。我相信有更快的方法可以做到这一点,但我确定这个方法是正确的。

def FREQUENCY(values, bands, max=None):
   counts = [0]*(len(bands)+1)
   for v in values:
       for i,b in enumerate(bands):
           if v <= b:
               counts[i] += 1
               break
           else if v > max:
               counts[-1] += 1
               break
   return counts
3

最好的选择是使用 numpy.histogram,不过如果你不想安装numpy,这里有一个和Excel一样好用的方法:

def frequency(data, bins):
    # work with local sorted copy of bins for performance
    bins = bins[:]
    bins.sort()
    freqs = [0] * (len(bins)+1)
    for item in data:
        for i, bin_val in enumerate(bins):
            if item <= bin_val:
                freqs[i] += 1
                break
        else:
            freqs[len(bins)] += 1
    return freqs

下面是Excel帮助文档中的一个例子,翻译成了Python代码:

>>> data = [79, 85, 78, 85, 50, 81, 95, 88, 97]
... bins = [70, 79, 89]
... print frequency(data, bins)
[1, 2, 4, 2]

这里有一个小小的区别。在Excel中,如果 bins 是空的,它会返回数据的长度作为一个整数。而这个Python版本则会把这个整数放在一个列表里返回。这样做的原因是,Python版本会返回一致的数据类型(而且依然能给出正确的答案)。

4
import numpy
numpy.histogram( [ <data> ], [ <bins> ] )

文档:

numpy.histogram(a, bins=10, range=None, normed=False, weights=None)

计算一组数据的直方图。

a : 类似数组的对象 输入的数据。直方图是对扁平化后的数组进行计算的。

bins : 整数或数值序列,可选 如果 bins 是一个整数,它定义了在给定范围内的等宽区间数量(默认是10)。如果 bins 是一个数值序列,它定义了区间的边界,包括最右边的边界, 允许区间宽度不均匀。

range : (浮点数, 浮点数),可选 区间的下限和上限。如果没有提供,范围就是 (a.min(), a.max())。超出范围的值会被忽略。

normed : 布尔值,可选 如果为 False,结果将包含每个区间中的样本数量。如果为 True,结果是 在该区间的概率密度函数的值,经过归一化处理,使得 在该范围内的积分为1。注意 直方图值的总和不会等于1,除非选择了宽度为1的区间;这不是一个 概率质量函数。

weights : 类似数组的对象,可选 一个与 a 形状相同的权重数组。a 中的每个值只 会根据其相关的权重对区间计数做贡献(而不是1)。 如果 normed 为 True,权重会被归一化,使得 在该范围内的密度积分保持为1。

返回值:

hist : 数组 直方图的值。有关可能的语义,请参见 normed 和 weights。

bin_edges : 浮点数类型的数组 返回区间的边界(长度为 hist + 1)。

你可能需要先安装 numpy

撰写回答