Эмпирическая функция распределения в Numpy

У меня есть следующий список значений:

x = [-0.04124324405924407, 0, 0.005249724476788287, 0.03599351958245578, -0.00252785423151014, 0.01007584102031178, -0.002510349639322063,...]

и я хочу вычислить эмпирическую функцию плотности, поэтому я думаю, что мне нужно вычислить эмпирическую интегральную функцию распределения, и я использовал этот код:

counts = np.asarray(np.bincount(x), dtype=float)
cdf = counts.cumsum() / counts.sum()

и тогда я вычисляю это значение:

print cdf[0.01007584102031178]

и я всегда получаю 1, поэтому я думаю, что сделал ошибку. Вы знаете, как это исправить? Спасибо!

2 ответа

Обычное определение эмпирического cdf - это число наблюдений, меньшее или равное данному значению, деленное на общее количество наблюдений. Используя 1d numpy массивы это x[x <= v].size / x.size (деление поплавка, в Python2 вам нужно from __future__ import division):

x = np.array([-0.04124324405924407,  0,
               0.005249724476788287, 0.03599351958245578,
              -0.00252785423151014,  0.01007584102031178,
              -0.002510349639322063])
v = 0.01007584102031178
print(x[x <= v].size / x.size)

Будет печатать 0.857142857143, (фактическое значение, если эмпирический cdf на 0.01007584102031178 составляет 6 / 7).

Это довольно дорого, если ваш массив большой, и вам нужно вычислить cdf для нескольких значений. В таких случаях вы можете сохранить отсортированную копию ваших данных и использовать np.searchsorted() узнать количество наблюдений <= v:

def ecdf(x):
    x = np.sort(x)
    def result(v):
        return np.searchsorted(x, v, side='right') / x.size
    return result

cdf = ecdf(x)
print(cdf(v))

Здесь две вещи идут не так, как надо:

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

Дополнительно, cdf обозначает нормальный массив NumPy в вашем случае. Индексы массива могут быть только целыми числами, поэтому ваш запрос cdf[0.01007584102031178] округляется до cdf[0],

Таким образом, в итоге ваш код сначала подсчитывает целые числа (все они округлены до 0), поэтому ваш нормализованный cdf впоследствии просто cdf == [ 1. ], Затем ваш индекс округляется в меньшую сторону, поэтому вы запрашиваете cdf[0] который равен 1.

Другие вопросы по тегам