2016-07-29 119 views
2

我有數據(PD系列),看起來像(每日股票收益,N = 555):無法在Matplotlib直方圖得到Y軸顯示的概率

S = perf_manual.returns 
S = S[~((S-S.mean()).abs()>3*S.std())] 

2014-03-31 20:00:00 0.000000 
2014-04-01 20:00:00 0.000000 
2014-04-03 20:00:00 -0.001950 
2014-04-04 20:00:00 -0.000538 
2014-04-07 20:00:00 0.000764 
2014-04-08 20:00:00 0.000803 
2014-04-09 20:00:00 0.001961 
2014-04-10 20:00:00 0.040530 
2014-04-11 20:00:00 -0.032319 
2014-04-14 20:00:00 -0.008512 
2014-04-15 20:00:00 -0.034109 
... 

我想生成從這個概率分佈圖。使用:

print stats.normaltest(S) 

n, bins, patches = plt.hist(S, 100, normed=1, facecolor='blue', alpha=0.75) 
print np.sum(n * np.diff(bins)) 

(mu, sigma) = stats.norm.fit(S) 
print mu, sigma 
y = mlab.normpdf(bins, mu, sigma) 
plt.grid(True) 
l = plt.plot(bins, y, 'r', linewidth=2) 

plt.xlim(-0.05,0.05) 
plt.show() 

我得到如下:

NormaltestResult(statistic=66.587382579416982, pvalue=3.473230376732532e-15) 
1.0 
0.000495624926242 0.0118790391467 

graph

我的印象中,y軸是一個數,但我想有概率代替。我怎麼做?我已經嘗試了很多StackOverflow的答案,並不能解決這個問題。

+0

你確定這些是計數?我想他們是概率密度值,因爲當你整合圖表時,你的圖形被歸一化爲1。你的x值範圍非常小。 – jotasi

+0

可能的話,概率密度並不是我最強烈的觀點。我怎樣才能至少把這些分成百分比? –

+0

你想要的百分比是多少?對於每個bin,數據在這個bin中的概率是多少?概率密度基本上意味着某個x範圍的密度積分給出了該範圍的概率。 – jotasi

回答

2

有沒有簡單的方法(我知道)使用plt.hist來做到這一點。但是,您可以使用np.histogram簡單地將數據分箱,然後以任何您想要的方式對數據進行規範化。如果我正確地理解了你,你希望數據顯示在給定分箱中找到一個點的概率,而不是概率分佈。這意味着你必須調整你的數據,使得所有bin的總和爲1.這可以簡單地通過做bin_probability = n/float(n.sum())來完成。

您將不會有一個正確的歸一化概率分佈函數(pdf)了,這意味着一個區間的積分不會是一個概率!這就是爲什麼您必須重新縮放mlab.normpdf以使其與直方圖具有相同的標準。因爲當你從正確歸一化的分級pdf開始時,所有分箱的總和乘以它們各自的寬度是1.現在你想只有分箱的總和等於1.所以比例因子是垃圾箱寬度。

因此,你最終的代碼是沿着線的東西:

import numpy as np 
import scipy.stats as stats 
import matplotlib.pyplot as plt 
import matplotlib.mlab as mlab 

# Produce test data 
S = np.random.normal(0, 0.01, size=1000) 

# Histogram: 
# Bin it 
n, bin_edges = np.histogram(S, 100) 
# Normalize it, so that every bins value gives the probability of that bin 
bin_probability = n/float(n.sum()) 
# Get the mid points of every bin 
bin_middles = (bin_edges[1:]+bin_edges[:-1])/2. 
# Compute the bin-width 
bin_width = bin_edges[1]-bin_edges[0] 
# Plot the histogram as a bar plot 
plt.bar(bin_middles, bin_probability, width=bin_width) 

# Fit to normal distribution 
(mu, sigma) = stats.norm.fit(S) 
# The pdf should not normed anymore but scaled the same way as the data 
y = mlab.normpdf(bin_middles, mu, sigma)*bin_width 
l = plt.plot(bin_middles, y, 'r', linewidth=2) 

plt.grid(True) 
plt.xlim(-0.05,0.05) 
plt.show() 

而導致的畫面將是:

enter image description here

+0

感謝你的消除我的困惑:) –