41

NumPyでCDFを作成したいのですが、私のコードは次のとおりです。

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)

アレイのそばを歩いていますが、プログラムの実行に時間がかかります。この機能を備えた関数が組み込まれていますね。

4

5 に答える 5

97

ヒストグラムを使用することは1つの解決策ですが、データをビニングする必要があります。これは、経験データのCDFをプロットするために必要ではありません。エントリF(x)の数が1つ少なくなりx、正確に測定値が表示される場所を数えます。したがって、サンプルを並べ替えると、各ポイントでカウントを1つ(または分数を1 / N)インクリメントし、一方を他方に対してプロットすると、「正確な」(つまり、ビン化されていない)経験累積分布関数が表示されます。

次のコードサンプルは、この方法を示しています

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()

以下を出力します

ここに画像の説明を入力してください

于 2015-05-26T13:33:11.933 に答える
24

コードが何をしているのかはよくわかりませんがhistbin_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])
于 2012-05-17T19:15:18.177 に答える
5

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.  ])
>>>
于 2014-11-21T18:48:23.067 に答える
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)
于 2015-08-26T15:08:53.217 に答える
-3

既成の答えがあるかどうかはわかりませんが、正確に行うべきことは、次のような関数を定義することです。

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

これはかなり高速になります。

于 2016-09-21T16:55:41.720 に答える