2012-06-30 17 views
6

Mam listę zawierającą ponad 100 000 wartości.Dzielenie listy na wiele list na podstawie rozmiaru bin

Potrzebuję podzielić listę na wiele mniejszych list w oparciu o konkretną szerokość pojemnika powiedz 0.1. Czy ktoś może mi pomóc, jak napisać program Pythona, aby to zrobić?

moja lista wygląda następująco

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

chciałbym mieć moc jak ten

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

Podałeś przykładowe dane wejściowe; proszę również podać oczekiwany wynik. – cheeken

Odpowiedz

5

Spowoduje to utworzenie dict gdzie każda wartość jest lista elementów, które pasują do kosza .

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

czy możesz mi powiedzieć, co się dzieje w linii 3. – user1492449

+0

@user tworzy lambdę. Jest to funkcja tymczasowa do odwzorowania wartości na identyfikatory bin. Sugerowałbym wyszukanie "python lambda", jeśli potrzebujesz więcej szczegółowych informacji. – Antimony

2

Czy tego chcesz? (Przykładowy wynik byłby pomocny :)

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 

plony:

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

ten SO pytanie assigning points to bins może być pomocne.

+1

histogramy podają liczbę elementów w koszu, ale nie same elementy. Próbowałem z tym. W pierwotnym pytaniu zamieściłem przykładowe dane wyjściowe. – user1492449

+0

@ user1492449 Dzięki za opinię, pomylę to i może opublikuję kolejną odpowiedź. W międzyczasie edytowałeś swój post, aby wydruki były bardziej czytelne. – Levon

3

to działa:

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)  

Wydruki:

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] 

Jak to działa:

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) 

Proponuję samouczek Python o tym sprawozdaniu.

+0

dzięki za odpowiedź i to działa. Czy możesz mi to wyjaśnić? – user1492449

6

Oto prosty i przyjemny sposób korzystania 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) 

Digitalizacja, zwraca tablicę wartości indeksu do kosza, że ​​każdy element wpada.

0

Możemy tworzyć kosze z more_itertools, biblioteki innej firmy.

Biorąc

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'] 

Kod

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'] 

Szczegóły

Możemy bin przez funkcję klucza, whi ch definiujemy, aby formatować liczby do pojedynczej precyzji, tj. -0.213 do -0.2.

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

Te pojemniki są dostępne za pomocą klawiszy zdefiniowanych przez funkcję klucza:

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

dostęp do wszystkich odbiorników przez powtarzanie klawiszy:

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]))) 

wyjściowe

-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'] 

listy zrozumienie i unpa cking to kolejna opcja (patrz przykład Code).

Zobacz także more_itertools docs więcej szczegółów.

0

Binning można zrobić z 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'] 

Uwaga: funkcja ta zakłada prosty klucz wartości w iterable są między -0.0 a -10.0. Rozważ lambda x: "{:.1f}".format(float(x)) dla ogólnych przypadków.

Zobacz także tym post Szczegółowe informacje na temat groupby prac.

Powiązane problemy