2010-04-26 58 views
3

我有一個包含值對的2-d數組,我想通過x值的不同bin創建y值的boxplot。即如果陣列是:在Python中使用numpy和scipy在matplotlib中創建binned boxplot

my_array = array([[1, 40.5], [4.5, 60], ...]]) 

然後我想倉my_array [:,0],然後對每個倉的,產生相應的my_array的箱線圖[:,1]的值落入每個框。所以最後我希望情節包含許多箱子 - 許多箱子情節。

我試過如下:

min_x = min(my_array[:, 0]) 
max_x = max(my_array[:, 1]) 

num_bins = 3 
bins = linspace(min_x, max_x, num_bins) 
elts_to_bins = digitize(my_array[:, 0], bins) 

然而,這給了我在範圍從1到3,我想我應該得到0基於指數的垃圾箱elts_to_bins價值觀,我只是想3個箱。我假設這是由於一些棘手的問題,如何在空間和數字化之間表現垃圾箱。

實現此目的的最簡單方法是什麼?我希望num_bins-許多等間隔的箱子,第一個箱子包含數據的下半部分,而上層箱子包含上半部分......即,我希望每個數據點落入某個箱子,以便我可以製作一個箱形圖。

謝謝。

回答

4

numpy的有dedicated function創建直方圖的方式,你需要:

histogram(a, bins=10, range=None, normed=False, weights=None, new=None) 

,您可以使用這樣的:

(hist_data, bin_edges) = histogram(my_array[:,0], weights=my_array[:,1]) 

這裏的關鍵點是使用weights參數:每個值a[i]將貢獻weights[i]直方圖。例如:

a = [0, 1] 
weights = [10, 2] 

描述在x = 0 10分和2分在x = 1

可以設置箱,或倉限度的數量,與所述bins參數(見official documentation爲更多細節)。

直方圖可以再用像被畫在:

bar(bin_edges[:-1], hist_data) 

如果你只需要做一個直方圖情節,類似hist()功能可以直接繪製直方圖:

hist(my_array[:,0], weights=my_array[:,1]) 
+0

我不明白爲什麼在閱讀文檔後使用「權重」 - 你能解釋一下嗎?如果重點只是將元素分配給垃圾箱,我不明白爲什麼重量應該扮演一個角色。 – user248237dfsf 2010-04-30 05:03:26

+0

我編輯了答案,以便更詳細地解釋權重參數的作用。如果您認爲答案有用,請大拇指! :) – EOL 2010-04-30 07:22:36

+1

其實,不幸的是,np.histogram不會做他所需要的。他需要落入每個垃圾箱的實際值,以便爲每個垃圾箱製作箱形圖。 (或者那是我的理解,無論如何,糾正我,如果我錯了,那裏!)權重參數只是將每個值乘以每個權重,所以不是將1加到箱中的計數中,而是將權重[i] 。這與將另一個數組中的值歸併爲一個數組的效果不同,並且無論如何不返回落入每個數組中的數組的子集。 (或者,也許我完全誤解了什麼?) – 2010-04-30 20:08:34

6

你得到的第三個數組的最大值(我假設你有一個錯字,並且max_x應該是「max(my_array [:,0])」而不是「max(my_array [:,1])「)。您可以通過將1(或任何正數)加到最後一個箱來避免這種情況。另外,如果我正確地理解了你,你想用另一個變量來存儲一個變量,所以下面的例子顯示了這個變量。如果你正在使用recarrays(速度慢得多),那麼matplotlib.mlab中也有幾個函數(例如mlab.rec_groupby等)可以做這種事情。

反正到最後,你可能有這樣的事情(在y中的值斌X,假設X和Y是相同的長度)

def bin_by(x, y, nbins=30): 
    """ 
    Bin x by y. 
    Returns the binned "x" values and the left edges of the bins 
    """ 
    bins = np.linspace(y.min(), y.max(), nbins+1) 
    # To avoid extra bin for the max value 
    bins[-1] += 1 

    indicies = np.digitize(y, bins) 

    output = [] 
    for i in xrange(1, len(bins)): 
     output.append(x[indicies==i]) 

    # Just return the left edges of the bins 
    bins = bins[:-1] 

    return output, bins 

作爲一個簡單的例子:

In [3]: x = np.random.random((100, 2)) 

In [4]: binned_values, bins = bin_by(x[:,0], x[:,1], 2) 

In [5]: binned_values 
Out[5]: 
[array([ 0.59649575, 0.07082605, 0.7191498 , 0.4026375 , 0.06611863, 
     0.01473529, 0.45487203, 0.39942696, 0.02342408, 0.04669615, 
     0.58294003, 0.59510434, 0.76255006, 0.76685052, 0.26108928, 
     0.7640156 , 0.01771553, 0.38212975, 0.74417014, 0.38217517, 
     0.73909022, 0.21068663, 0.9103707 , 0.83556636, 0.34277006, 
     0.38007865, 0.18697416, 0.64370535, 0.68292336, 0.26142583, 
     0.50457354, 0.63071319, 0.87525221, 0.86509534, 0.96382375, 
     0.57556343, 0.55860405, 0.36392931, 0.93638048, 0.66889756, 
     0.46140831, 0.01675165, 0.15401495, 0.10813141, 0.03876953, 
     0.65967335, 0.86803192, 0.94835281, 0.44950182]), 
array([ 0.9249993 , 0.02682873, 0.89439141, 0.26415792, 0.42771144, 
     0.12292614, 0.44790357, 0.64692616, 0.14871052, 0.55611472, 
     0.72340179, 0.55335053, 0.07967047, 0.95725514, 0.49737279, 
     0.99213794, 0.7604765 , 0.56719713, 0.77828727, 0.77046566, 
     0.15060196, 0.39199123, 0.78904624, 0.59974575, 0.6965413 , 
     0.52664095, 0.28629324, 0.21838664, 0.47305751, 0.3544522 , 
     0.57704906, 0.1023201 , 0.76861237, 0.88862359, 0.29310836, 
     0.22079126, 0.84966201, 0.9376939 , 0.95449215, 0.10856864, 
     0.86655289, 0.57835533, 0.32831162, 0.1673871 , 0.55742108, 
     0.02436965, 0.45261232, 0.31552715, 0.56666458, 0.24757898, 
     0.8674747 ])] 

希望幫助一下!

相關問題