【问题标题】:Numpy cumulative distribution function (CDF)Numpy 累积分布函数 (CDF)
【发布时间】:2015-04-27 09:03:42
【问题描述】:

我有一个值数组,并使用 numpy.histogram 创建了数据的直方图,如下所示:

histo = numpy.histogram(arr, nbins)

其中 nbins 是从数据范围 (max-min) 除以所需的 bin 宽度得出的 bin 数。

根据输出,我使用以下方法创建了一个累积分布函数:

cdf = np.cumsum(histo[0])
normCdf = cdf/np.amax(cdf)

但是,我需要一个与原始数组 (arr) 中的值相对应的 normCdf 值数组。例如,如果原始数组 arr 中的值接近 arr 的最小值,则其对应的 normCdf 值将很高(即 0.95)。 (在本例中,当我处理雷达数据时,我的数据以分贝为单位,为负数。因此,CDF 达到最大值时为最小值。)

从概念上讲,我正在努力实现一个数组,其中数组中的每个值在 CDF 下都有对应的值(normCdf 值)。任何帮助,将不胜感激。带有 cdf 的直方图如下。

【问题讨论】:

  • 这里有几点需要注意:np.histogram 有一个 density 关键字,您可能希望将其用于经验累积密度。图中的红色曲线不是cdf,而可能是1-cdf。使用 cumsum 是正确的方法,但是您会得到一个函数,将每个 bin 的位置映射到累积密度。
  • 我查看了密度选项,但它返回的是 pdf 而不是 cdf,其中曲线下面积的积分为 1,而不是累计总数。我很高兴我有我需要的正确值,但我想使用原始数组索引它们
  • 最简单的方法可能是使用 statsmodels 中的经验累积密度函数实现:statsmodels.sourceforge.net/0.6.0/generated/…
  • 解决了它遍历原始数组中的值并计算 (originalArray - minOfOriginalArray)/binwidth 并使用结果来索引 CDF 数组
  • @NathanThomas 您介意详细说明您的解决方案吗?

标签: python arrays numpy statistics


【解决方案1】:

这是旧的,但可能仍然对某人有帮助。

考虑 OP 的最后一句话:

从概念上讲,我正在努力实现一个数组,其中数组中的每个值在 CDF 下都有对应的值(normCdf 值)。

如果我理解正确,OP 所要求的实际上归结为数组元素的(标准化)序数排名

数组元素i的序数秩基本上表示数组中有多少元素的值小于元素i的值。这相当于离散累积密度。

序数排名与按以下等式排序有关(其中u 是未排序的列表):

u == [sorted(u)[i] for i in ordinal_rank(u)]

基于implementation of scipy.stats.rankdata,可以按如下方式计算序数:

def ordinal_rank(data):
    rank = numpy.empty(data.size)
    rank[numpy.argsort(data)] = numpy.arange(data.size)
    return rank

所以,回答 OP 的问题:

然后可以按如下方式计算与 OP 的 arr 中的值对应的归一化(经验)累积密度:

normalized_cdf = ordinal_rank(arr) / len(arr)

结果可以使用:

pyplot.plot(arr, normalized_cdf, marker='.', linestyle='')

请注意,如果您只需要情节,还有一种更简单的方法:

n = len(arr)
pyplot.plot(numpy.sort(arr), numpy.arange(n) / n)

最后,我们可以通过绘制如下的累积归一化直方图来验证这一点(使用任意数量的 bin):

pyplot.hist(arr, bins=100, cumulative=True, density=True)

这是一个比较这三种方法的示例,累积直方图使用 30 个 bin:

【讨论】:

    猜你喜欢
    • 2012-06-08
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 2021-10-10
    • 2012-05-25
    • 2022-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多