scipy.stats.

binned_statistic#

scipy.stats.binned_statistic(x, values, statistic='mean', bins=10, range=None)[source]#

计算一个或多个数据集的分类统计信息。

这是直方图函数的一种概括。直方图将空间划分为若干个区间,并返回每个区间内点的数量。此函数允许计算每个区间内值(或一组值)的总和、均值、中值或其他统计信息。

参数:
x(N,) array_like

要分类值的一个序列。

values(N,) array_like 或 (N,) array_like 的列表

将根据其计算统计信息的数据。此信息必须与 x 的形状相同,或者是一组序列(每个序列的形状与 x 相同)。如果 values 是一个序列集,则将独立计算每个统计信息。

statistic字符串或可调用对象,可选

要计算的统计信息(默认为“均值”)。以下统计信息可用

  • ‘mean’ :计算每个仓中数据点的均值。空仓用 NaN 表示。

  • ‘std’ :计算每个仓的标准差。用 ddof=0 内含计算。

  • ‘median’ :计算每个仓中数据点的中位数。空仓用 NaN 表示。

  • ‘count’ :计算每个仓中数据点的数量。和未加权直方图相同。values 数组不引用。

  • ‘sum’ :计算每个仓中数据点的和。和加权直方图相同。

  • ‘min’ :计算每个仓中数据点的最小值。空仓用 NaN 表示。

  • ‘max’ :计算每个仓中数据点的最大值。空仓用 NaN 表示。

  • function :用户自定义函数,它接受一个 1D 值数组,并输出单个数值统计。此函数将调用每个仓中的值。空仓用 function([]) 表示,如果这里返回错误,则用 NaN 表示。

binsint 或标量序列,可选

如果 bins 是 int,则它将定义给定范围内相等宽度的仓数(默认值为 10)。如果 bins 是序列,则它将定义仓边缘,包括最右端的边缘,从而可以使用非均匀仓宽。在 x 中小于最低仓边缘的值被分配到仓号 0,高于最高仓的值被分配到 bins[-1]。如果指定了仓边缘,则仓数为 (nx = len(bins)-1)。

range(float, float) 或 [(float, float)],可选

仓的下限和上限。如果未提供,则范围仅为 (x.min(), x.max())。不计在范围外的值。

返回值:
statistic数组

每个仓中选定统计值。

bin_edgesdtype 为浮点数的数组

返回仓边缘 (length(statistic)+1)

binnumber: 整数的 1-D ndarray

每个 x 值归属的仓(与 bin_edges 相对应)的索引。与 values 等长。binnumber 为 i 意味着对应值在 (bin_edges[i-1], bin_edges[i]) 之间。

说明

除了最后一个(最右侧)的箱外,其他所有箱都是半开的。换句话说,如果 bin[1, 2, 3, 4],那么第一个箱是 [1, 2)(包括 1,但不包括 2),第二个箱是 [2, 3)。不过,最后一个箱是 [3, 4],这包括 4。

0.11.0 版中添加。

示例

>>> import numpy as np
>>> from scipy import stats
>>> import matplotlib.pyplot as plt

首先看几个基本示例

在给定样本范围内创建两个均匀分布的箱,并计算每个箱中相应的值得总和

>>> values = [1.0, 1.0, 2.0, 1.5, 3.0]
>>> stats.binned_statistic([1, 1, 2, 5, 7], values, 'sum', bins=2)
BinnedStatisticResult(statistic=array([4. , 4.5]),
        bin_edges=array([1., 4., 7.]), binnumber=array([1, 1, 1, 2, 2]))

也可以传递多个值的数组。该统计数据独立于每组计算

>>> values = [[1.0, 1.0, 2.0, 1.5, 3.0], [2.0, 2.0, 4.0, 3.0, 6.0]]
>>> stats.binned_statistic([1, 1, 2, 5, 7], values, 'sum', bins=2)
BinnedStatisticResult(statistic=array([[4. , 4.5],
       [8. , 9. ]]), bin_edges=array([1., 4., 7.]),
       binnumber=array([1, 1, 1, 2, 2]))
>>> stats.binned_statistic([1, 2, 1, 2, 4], np.arange(5), statistic='mean',
...                        bins=3)
BinnedStatisticResult(statistic=array([1., 2., 4.]),
        bin_edges=array([1., 2., 3., 4.]),
        binnumber=array([1, 2, 1, 2, 3]))

第二个示例中,我们生成了风速与帆船速度之间的随机数据,然后确定在特定风速下船的速度

>>> rng = np.random.default_rng()
>>> windspeed = 8 * rng.random(500)
>>> boatspeed = .3 * windspeed**.5 + .2 * rng.random(500)
>>> bin_means, bin_edges, binnumber = stats.binned_statistic(windspeed,
...                 boatspeed, statistic='median', bins=[1,2,3,4,5,6,7])
>>> plt.figure()
>>> plt.plot(windspeed, boatspeed, 'b.', label='raw data')
>>> plt.hlines(bin_means, bin_edges[:-1], bin_edges[1:], colors='g', lw=5,
...            label='binned statistic of data')
>>> plt.legend()

现在,我们可以使用 binnumber 选择风速在 1 以下的所有数据点

>>> low_boatspeed = boatspeed[binnumber == 0]

最后,我们将使用 bin_edgesbinnumber 绘制一个分布图,该图在常规分布图和概率分布函数上显示每个箱的均值和分布

>>> x = np.linspace(0, 5, num=500)
>>> x_pdf = stats.maxwell.pdf(x)
>>> samples = stats.maxwell.rvs(size=10000)
>>> bin_means, bin_edges, binnumber = stats.binned_statistic(x, x_pdf,
...         statistic='mean', bins=25)
>>> bin_width = (bin_edges[1] - bin_edges[0])
>>> bin_centers = bin_edges[1:] - bin_width/2
>>> plt.figure()
>>> plt.hist(samples, bins=50, density=True, histtype='stepfilled',
...          alpha=0.2, label='histogram of data')
>>> plt.plot(x, x_pdf, 'r-', label='analytical pdf')
>>> plt.hlines(bin_means, bin_edges[:-1], bin_edges[1:], colors='g', lw=2,
...            label='binned statistic of data')
>>> plt.plot((binnumber - 0.5) * bin_width, x_pdf, 'g.', alpha=0.5)
>>> plt.legend(fontsize=10)
>>> plt.show()
../../_images/scipy-stats-binned_statistic-1_00.png
../../_images/scipy-stats-binned_statistic-1_01.png