2016-04-01 3 views
0

Я следующий список значений:Эмпирическая функция распределения в 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, поэтому, думаю, я допустил ошибку. Вы знаете, как это исправить? Спасибо!

ответ

1

Есть две вещи неправильно здесь:

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

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

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

+0

Большое спасибо. Должен ли я сделать это: counts = np.asarray (np.histogram (x))? Я не очень хорошо разбираюсь в таких методах ... – Angelina

+0

Нет, вам не нужно приводить результаты NumPy в массив, они уже являются массивами NumPy. – jojonas

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)) 
Смежные вопросы