Как вывести эмпирический cdf на печать в matplotlib в Python?

Как я могу вывести эмпирический CDF на печать массива чисел в matplotlib в Python? Я ищу cdf аналог pylab's, "тсс" функционируют.

Одна вещь, о которой я могу думать:

from scipy.stats import cumfreq
a = array([...]) # my array of numbers
num_bins =  20
b = cumfreq(a, num_bins)
plt.plot(b)

Это корректно хотя? Существует ли более легкий/лучше путь?

спасибо.

61
задан bmu 5 June 2012 в 07:56
поделиться

4 ответа

Похоже, это (почти) именно то, что вы хотите. Два момента:

Во-первых, результаты представляют собой кортеж из четырех элементов. Третий - это размер бинов. Второй - начальная точка наименьшего бина. Первый - количество точек в или под каждым бином. (Последнее - количество точек вне пределов, но поскольку вы не задали их, все точки будут разбиты на бины.)

Во-вторых, вам нужно изменить масштаб результатов, чтобы конечное значение было равно 1, чтобы следовать обычным соглашениям CDF, но в остальном все правильно.

Вот что он делает под капотом:

def cumfreq(a, numbins=10, defaultreallimits=None):
    # docstring omitted
    h,l,b,e = histogram(a,numbins,defaultreallimits)
    cumhist = np.cumsum(h*1, axis=0)
    return cumhist,l,b,e

Он выполняет гистограммирование, затем выдает кумулятивную сумму подсчетов в каждом бине. Таким образом, i-е значение результата - это количество значений массива, меньших или равных максимуму i-го бина. Таким образом, конечное значение равно размеру исходного массива.

Наконец, чтобы построить график, вам нужно будет использовать начальное значение бина и размер бина, чтобы определить, какие значения оси x вам понадобятся.

Другой вариант - использовать numpy.histogram, который может выполнить нормализацию и вернуть края бина. Вам нужно будет самостоятельно выполнить кумулятивную сумму результирующих отсчетов.

a = array([...]) # your array of numbers
num_bins = 20
counts, bin_edges = numpy.histogram(a, bins=num_bins, normed=True)
cdf = numpy.cumsum(counts)
pylab.plot(bin_edges[1:], cdf)

(bin_edges[1:] - верхний край каждого бина.)

17
ответ дан 24 November 2019 в 16:58
поделиться

Что вы хотите сделать с CDF? Чтобы построить это, это только начало. Вы можете попробовать несколько разных значений, например:

from __future__ import division
import numpy as np
from scipy.stats import cumfreq
import pylab as plt

hi = 100.
a = np.arange(hi) ** 2
for nbins in ( 2, 20, 100 ):
    cf = cumfreq(a, nbins)  # bin values, lowerlimit, binsize, extrapoints
    w = hi / nbins
    x = np.linspace( w/2, hi - w/2, nbins )  # care
    # print x, cf
    plt.plot( x, cf[0], label=str(nbins) )

plt.legend()
plt.show()

Гистограмма перечисляет различные правила для количества ящиков, например num_bins ~ sqrt (len (a)) .

(Мелкий шрифт: здесь происходят две совершенно разные вещи,

  • биннинг / гистограмма необработанных данных
  • график интерполирует плавную кривую через, скажем, 20 биннированных значений.

Любой из них может уходить от "неуклюжих" данных или имеет длинные хвосты, даже для одномерных данных - двухмерные, трехмерные данные становятся все труднее.
Смотрите также Оценка плотности а также с использованием оценки плотности ядра scipy гаусса ).

3
ответ дан 24 November 2019 в 16:58
поделиться

Вы можете использовать функцию ECDF из библиотеки scikits.statsmodels:

import numpy as np
import scikits.statsmodels as sm
import matplotlib.pyplot as plt

sample = np.random.uniform(0, 1, 50)
ecdf = sm.tools.ECDF(sample)

x = np.linspace(min(sample), max(sample))
y = ecdf(x)
plt.step(x, y)

В версии 0.4 scicits.statsmodels была переименована в statsmodels. ECDF теперь находится в модуле distributions (в то время как statsmodels.tools.tools.ECDF обесценился).

import numpy as np
import statsmodels.api as sm # recommended import according to the docs
import matplotlib.pyplot as plt

sample = np.random.uniform(0, 1, 50)
ecdf = sm.distributions.ECDF(sample)

x = np.linspace(min(sample), max(sample))
y = ecdf(x)
plt.step(x, y)
plt.show()
70
ответ дан 24 November 2019 в 16:58
поделиться

У меня есть тривиальное дополнение к методу AFoglia, для нормализации CDF

n_counts,bin_edges = np.histogram(myarray,bins=11,normed=True) 
cdf = np.cumsum(n_counts)  # cdf not normalized, despite above
scale = 1.0/cdf[-1]
ncdf = scale * cdf

Нормализация histo делает его интеграл единицей, что означает, что cdf не будет нормализован. Приходится масштабировать его самостоятельно.

3
ответ дан 24 November 2019 в 16:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: