2016-08-04 20 views
0

我有一個關於重新綁定數字列表的問題,具有所需的bin寬度。這基本上是一個頻率直方圖的功能,但我不想要這個圖,就是每個bin的bin數和出現次數。重新綁定Python中的數字列表

到目前爲止,我已經寫了一些代碼,可以做我想做的,但效率不高。給定一個列表a,爲了與垃圾箱寬度等於3到熱病,我已經寫了以下內容:

import os, sys, math 
import numpy as np 

# list of numbers 
a = list(range(3000)) 

# number of entries 
L = int(len(a)) 

# desired bin width 
W = 3 

# number of bins with width W 
N = int(L/W) 

# definition of new empty array 
a_rebin = np.zeros((N, 2)) 

# cycles to populate the new rebinned array 
for n in range(0,N): 
    k = 0 
    for i in range(0,L): 
     if a[i] >= (W*n) and a[i] < (W+W*n): 
      k = k+1 
    a_rebin[n]=[W*n,k] 

# print 
print a_rebin 

現在,這不正是我想要的,但我認爲這是沒有那麼聰明,因爲它讀取整個列表N次,與N箱數。小列表沒問題。但是,由於我必須處理非常大的列表和相當小的bin寬度,因此這會轉化爲巨大的值N,並且整個過程需要很長時間(小時...)。你有什麼想法來改進這個代碼嗎?先謝謝你!

回答

1

如果使用a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],您的解決方案是:

[0 3]
[3. 3]
[6 3]

如何你解釋這個?間隔是0..2,3..5,6..8?我想你錯過了一些東西。

使用numpy.histogram()

hist, bin_edges = numpy.histogram(a, bins=int(len(a)/W)) 
print(hist) 
print(bin_edges) 

輸出:

[3 3 4]
[0 3 6 9]

我們有4個值在bin_edges中:0,3,6和9.除最後一個(右側)以外的所有倉都是半開放的。這意味着我們有3個區間[0,3),[3,6]和[6,9],每個區間有3個,3個和4個元素。
您可以定義自己的垃圾箱。

import numpy 
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
bins=[0,1,2] 
hist, bin_edges = numpy.histogram(a, bins=bins) 
print(hist) 
print(bin_edges) 

輸出:

[1 2]
[0 1 2]

現在你有在[0,1)和2個元素1種元素[ 1,2]。

+0

嗯,是的,我的算法錯過了最後一個bin,但是你的解決方案將最後兩個bin合併在一起,或者看起來如此。對於帶寬爲3的[0,1,2,3,4,5,6,7,8,9],我預計出現次數爲[3,3,3,1],但是會得到[3,3,4 ]。如果我選擇bindwith 5,我期望出現[5,5],但是這段代碼給了我不理解的bin邊界,[0. 4.5 9.] ...對不起,我不太習慣python ... – urgeo

+0

我們在bin_edges中有4個值:0,3,6和9.除最後一個(右側)以外的所有塊都是半開放的。這意味着我們有3個區間[0,3),[3,6]和[6,9],每個區間有3個,3個和4個元素。你可以定義你自己的bin:[0,1,2],現在你在[0,1]中有1個元素,在[1,2]中有2個元素。現在可以? –

0

numpy有一個名爲np.histogram的方法,它爲你工作。它也很好地擴展。