Подтвердить что ты не робот

Как получить кумулятивную функцию распределения с NumPy?

Я хочу создать CDF с NumPy, мой код следующий:

histo = np.zeros(4096, dtype = np.int32)
for x in range(0, width):
   for y in range(0, height):
      histo[data[x][y]] += 1
      q = 0 
   cdf = list()
   for i in histo:
      q = q + i
      cdf.append(q)

Я иду по массиву, но долго выполняю выполнение программы. Есть встроенная функция с этой функцией, не?

4b9b3361

Ответ 1

Я не совсем уверен, что делает ваш код, но если у вас есть hist и bin_edges массивы, возвращенные numpy.histogram, вы можете использовать numpy.cumsum для генерации суммарной суммы содержимого гистограммы.

>>> import numpy as np
>>> hist, bin_edges = np.histogram(np.random.randint(0,10,100), normed=True)
>>> bin_edges
array([ 0. ,  0.9,  1.8,  2.7,  3.6,  4.5,  5.4,  6.3,  7.2,  8.1,  9. ])
>>> hist
array([ 0.14444444,  0.11111111,  0.11111111,  0.1       ,  0.1       ,
        0.14444444,  0.14444444,  0.08888889,  0.03333333,  0.13333333])
>>> np.cumsum(hist)
array([ 0.14444444,  0.25555556,  0.36666667,  0.46666667,  0.56666667,
        0.71111111,  0.85555556,  0.94444444,  0.97777778,  1.11111111])

Ответ 2

Использование гистограммы - это одно решение, но оно включает в себя объединение данных. Это не обязательно для построения CDF эмпирических данных. Пусть F(x) будет подсчитывать, сколько записей меньше, чем x, тогда оно поднимается на единицу, точно там, где мы видим измерение. Таким образом, если мы сортируем наши выборки, то в каждой точке мы увеличиваем счет на единицу (или на долю на 1/N), а график один на другой, мы увидим "точный" (то есть неконденсированный) эмпирический CDF.

Следующий пример кода демонстрирует метод

import numpy as np
import matplotlib.pyplot as plt

N = 100
Z = np.random.normal(size = N)
# method 1
H,X1 = np.histogram( Z, bins = 10, normed = True )
dx = X1[1] - X1[0]
F1 = np.cumsum(H)*dx
#method 2
X2 = np.sort(Z)
F2 = np.array(range(N))/float(N)

plt.plot(X1[1:], F1)
plt.plot(X2, F2)
plt.show()

Он выводит следующие

enter image description here

Ответ 3

обновление для numpy версии 1.9.0. user545424 ответ не работает в 1.9.0. Это работает:

>>> import numpy as np
>>> arr = np.random.randint(0,10,100)
>>> hist, bin_edges = np.histogram(arr, density=True)
>>> hist = array([ 0.16666667,  0.15555556,  0.15555556,  0.05555556,  0.08888889,
    0.08888889,  0.07777778,  0.04444444,  0.18888889,  0.08888889])
>>> hist
array([ 0.1       ,  0.11111111,  0.11111111,  0.08888889,  0.08888889,
    0.15555556,  0.11111111,  0.13333333,  0.1       ,  0.11111111])
>>> bin_edges
array([ 0. ,  0.9,  1.8,  2.7,  3.6,  4.5,  5.4,  6.3,  7.2,  8.1,  9. ])
>>> np.diff(bin_edges)
array([ 0.9,  0.9,  0.9,  0.9,  0.9,  0.9,  0.9,  0.9,  0.9,  0.9])
>>> np.diff(bin_edges)*hist
array([ 0.09,  0.1 ,  0.1 ,  0.08,  0.08,  0.14,  0.1 ,  0.12,  0.09,  0.1 ])
>>> cdf = np.cumsum(hist*np.diff(bin_edges))
>>> cdf
array([ 0.15,  0.29,  0.43,  0.48,  0.56,  0.64,  0.71,  0.75,  0.92,  1.  ])
>>>

Ответ 4

В дополнение к решению Дэн. В случае, когда в вашем примере несколько значений идентификатора, вы можете использовать numpy.unique:

Z = np.array([1,1,1,2,2,4,5,6,6,6,7,8,8])
X, F = np.unique(Z, return_index=True)
F=F/X.size

plt.plot(X, F)

Ответ 6

Я не уверен, есть ли готовый ответ, то, что нужно сделать, - это определить такую ​​функцию, как:

def _cdf(x,data):
    return(sum(x>data))

Это будет довольно быстро.