2012-06-30 57 views
6

我有一個包含超過100,000個值的列表。基於bin大小將列表劃分爲多個列表

我需要根據特定的bin寬度將列表分成多個較小的列表,例如0.1。任何人都可以幫助我如何編寫一個Python程序來做到這一點?

我的列表看起來像這樣

-0.234 
-0.04325 
-0.43134 
-0.315 
-0.6322 
-0.245 
-0.5325 
-0.6341 
-0.5214 
-0.531 
-0.124 
-0.0252 

我想有這樣

list1 = [-0.04325, -0.0252] 
list2 = [-0.124] 
list3 = [-0.234, -0.245 ] 
list4 = [-0.315] 
list5 = [-0.43134] 
list6 = [-0.5325, -0.5214, -0.531] 
list7 = [-0.6322, -0.6341] 
+3

您提供了示例輸入;還請提供預期產出。 – cheeken

回答

5

這樣的輸出將創建一個字典,其中每個值是適合在一個倉的元素列表。

import collections 
bins = collections.defaultdict(list) 
binId = lambda x: int(x*10) 
for val in vals: 
    bins[binId(val)].append(val) 
+0

你能告訴我第3行發生了什麼嗎? – user1492449

+0

@user它正在創建一個lambda。這是將值映射到bin ID的臨時函數。如果你想要更深入的信息,我建議搜索'python lambda'。 – Antimony

2

這是你想要的嗎? (樣本輸出會有所幫助:)

f = [-0.234, -0.04325, -0.43134, -0.315, -0.6322, -0.245, 
    -0.5325, -0.6341, -0.5214, -0.531, -0.124, -0.0252] 

import numpy as np 
data = np.array(f) 
hist, edges = np.histogram(data, bins=10) 
print hist 

產量:

[2 3 0 1 0 1 2 0 1 2] 

這太問題assigning points to bins可能會有所幫助。

+1

直方圖給出了元素的數量,但不包含元素本身。我已經嘗試過。我在原始問題中包含了一個示例輸出。 – user1492449

+0

@ user1492449感謝您的反饋,我會仔細考慮這一點,也許會發布另一個答案。同時編輯您的帖子,使輸出更具可讀性。 – Levon

3

這工作:

l=[-0.234, -0.04325, -0.43134, -0.315, -0.6322, -0.245, 
-0.5325, -0.6341, -0.5214, -0.531, -0.124, -0.0252] 

d={} 
for k,v in zip([int(i*10) for i in l],l): 
    d.setdefault(k,[]).append(v) 

LoL=[d[e] for e in sorted(d.keys(), reverse=True)] 

for i,l in enumerate(LoL,1): 
    print('list',i,l)  

打印:

list 1 [-0.04325, -0.0252] 
list 2 [-0.124] 
list 3 [-0.234, -0.245] 
list 4 [-0.315] 
list 5 [-0.43134] 
list 6 [-0.5325, -0.5214, -0.531] 
list 7 [-0.6322, -0.6341] 

工作原理:

1: The list 
>>> l=[-0.234, -0.04325, -0.43134, -0.315, -0.6322, -0.245, 
... -0.5325, -0.6341, -0.5214, -0.531, -0.124, -0.0252] 

2: Produce the keys: 
>>> [int(i*10) for i in l] 
[-2, 0, -4, -3, -6, -2, -5, -6, -5, -5, -1, 0] 

3: Produce tuples to put in the dict: 
>>> zip([int(i*10) for i in l],l) 
[(-2, -0.234), (0, -0.04325), (-4, -0.43134), (-3, -0.315), (-6, -0.6322), 
(-2, -0.245), (-5, -0.5325), (-6, -0.6341), (-5, -0.5214), (-5, -0.531), 
(-1, -0.124), (0, -0.0252)] 

4: unpack the tuples into k,v and loop over the list 
>>>for k,v in zip([int(i*10) for i in l],l): 

5: add k key to a dict (if not there) and append the float value to a list associated 
    with that key: 
    d.setdefault(k,[]).append(v) 

我建議在這些語句一個Python教程。

+0

感謝您的答覆,它的工作原理。你能解釋我這個嗎? – user1492449

6

下面是使用numpys digitize一個簡單又好的方法:

>>> import numpy as np 
>>> mylist = np.array([-0.234, -0.04325, -0.43134, -0.315, -0.6322, -0.245, 
         -0.5325, -0.6341, -0.5214, -0.531, -0.124, -0.0252]) 
>>> bins = np.arange(0,-1,-0.1) 
>>> for i in xrange(1,10): 
...  mylist[np.digitize(mylist,bins)==i] 
... 
array([-0.04325, -0.0252 ]) 
array([-0.124]) 
array([-0.234, -0.245]) 
array([-0.315]) 
array([-0.43134]) 
array([-0.5325, -0.5214, -0.531 ]) 
array([-0.6322, -0.6341]) 
array([], dtype=float64) 
array([], dtype=float64) 

數字化,返回與該各元素落入倉中的索引值的數組。

0

我們可以用第三方庫more_itertools製作垃圾箱。

鑑於

iterable = (
    "-0.234 -0.04325 -0.43134 -0.315 -0.6322 -0.245 " 
    "-0.5325 -0.6341 -0.5214 -0.531 -0.124 -0.0252" 
).split() 

iterable 
# ['-0.234', '-0.04325', '-0.43134', '-0.315', '-0.6322', '-0.245', '-0.5325', '-0.6341', '-0.5214', '-0.531', '-0.124', '-0.0252'] 

代碼

import more_itertools as mit 


keyfunc = lambda x: float("{:.1f}".format(float(x))) 
bins = mit.bucket(iterable, key=keyfunc) 

keys = [-0.0,-0.1,-0.2, -0.3,-0.4,-0.5,-0.6] 
a,b,c,d,e,f,g = [list(bins[k]) for k in keys] 
c 
# ['-0.234', '-0.245'] 

詳細

我們可以通過該鍵功能斌,WHI我們定義將數字格式化爲單精度,即-0.213-0.2

keyfunc = lambda x: float("{:.1f}".format(float(x))) 
bins = mit.bucket(iterable, key=keyfunc) 

這些垃圾箱是由按鍵功能定義的鍵訪問:

c = list(bins[-0.2]) 
c 
# ['-0.234', '-0.245'] 

訪問所有的垃圾箱是通過遍歷鍵:

f = lambda x: float("{:.1f}".format(float(x))) 
bins = mit.bucket(iterable, key=keyfunc) 

keys = [-0.0,-0.1,-0.2, -0.3,-0.4,-0.5,-0.6] 
for k in keys: 
    print("{} --> {}".format(k, list(bins[k]))) 

輸出

-0.0 --> ['-0.04325', '-0.0252'] 
-0.1 --> ['-0.124'] 
-0.2 --> ['-0.234', '-0.245'] 
-0.3 --> ['-0.315'] 
-0.4 --> ['-0.43134'] 
-0.5 --> ['-0.5325', '-0.5214', '-0.531'] 
-0.6 --> ['-0.6322', '-0.6341'] 

名單理解和unpa cking是另一種選擇(請參閱代碼示例)。

另請參閱more_itertools docs瞭解更多詳情。

0

分級可以用itertools.groupby做到:

import itertools as it 


iterable = ['-0.234', '-0.04325', '-0.43134', '-0.315', '-0.6322', '-0.245', 
      '-0.5325', '-0.6341', '-0.5214', '-0.531', '-0.124', '-0.0252'] 

a,b,c,d,e,f,g = [list(g) for k, g in it.groupby(sorted(iterable), key=lambda x: x[:4])] 
c 
# ['-0.234', '-0.245'] 

注:這個簡單的按鍵功能,假設在迭代的值是-0.0和-10.0之間。對於一般情況,請考慮lambda x: "{:.1f}".format(float(x))

有關groupby如何工作的詳細信息,請參閱此post