2013-08-23 68 views
3

我使用的gaussian_kde功能SciPy的,以產生核密度估計:密度估計值與大陣列

from scipy.stats.kde import gaussian_kde 
from scipy.stats import norm 
from numpy import linspace,hstack 
from pylab import plot,show,hist 

# creating data with two peaks 
sampD1 = norm.rvs(loc=-1.0,scale=1,size=300) 
sampD2 = norm.rvs(loc=2.0,scale=0.5,size=300) 
samp = hstack([sampD1,sampD2]) 

# obtaining the pdf (my_pdf is a function!) 
my_pdf = gaussian_kde(samp) 

# plotting the result 
x = linspace(-5,5,100) 
plot(x,my_pdf(x),'r') # distribution function 
hist(samp,normed=1,alpha=.3) # histogram 
show() 

上面的代碼的工作,但可以是具有一個非常大的數量的樣本的過分慢。

而不是將我的樣本存儲在數組中,我有一個關鍵字/值對爲value: counts的字典。例如,陣列[1, 1, 1, 2, 2, 3]將在此直方圖字典中編碼爲:

{1:3, 2:2, 3:1}

我的問題是,如何使用字典數據結構生成內核密度估計值?作爲一個示例輸入,請考慮這本字典,其中值6看到2081次:

samp = {1: 1000, 2: 2800, 3: 6900, 4: 4322:, 5: 2300, 6: 2081} 

在此先感謝您的幫助。

+0

嗯,SciPy的的gaussian_kde只需陣列狀的結構作爲輸入。我相當肯定你不能餵它字典。此外,您的新數據結構僅壓縮輸入數據,但不會改變處理速度。 – lucasg

回答

2

您可以自己做高斯KDE:您只需首先創建具有足夠小步長的簡單直方圖。然後卷積使用與高斯結果fftconvolve (scipy.signal.fftconvolve)

import numpy as np, numpy.random,scipy,scipy.stats,scipy.signal,matplotlib.pyplot as plt 
N = 1e5 
minx = -10 
maxx = 10 
bins = 10000 
w = 0.1 # kernel sigma 

xs1 = np.random.normal(0, 1, size=N) 
xs2 = np.random.normal(1.9, 0.01, size=N) 
xs = np.r_[xs1, xs2] 
hh,loc = scipy.histogram(xs, range=(minx, maxx), bins=bins) 
kernel = scipy.stats.norm.pdf((loc[1:]+loc[:-1]) * .5, 0, w) 
kde = scipy.signal.fftconvolve(hh, kernel, 'same') 
plt.plot((loc[1:] + loc[:-1])*.5, kde) 
1

關於第一個問題:

如果你的數據是單變量,那麼你可以使用核密度估計這是更快的FFT版本。 例如在statsmodels http://statsmodels.sourceforge.net/devel/generated/statsmodels.nonparametric.kde.KDEUnivariate.html

對第二個問題:

如果你已經有了一個柱狀圖爲您的數據,那麼你可以使用直方圖平滑化。但是我不知道python中的任何函數都可以做到這一點。 statsmodels中的fft版本首先將數據裝箱。第二步與直方圖的卷積類似。有可能使用類似的直方圖數據。