Divida una lista en varias listas según el tamaño de un contenedor

Tengo una lista que contiene más de 100,000 valores.

Necesito dividir la lista en varias listas más pequeñas basadas en un ancho de contenedor específico, por ejemplo, 0.1. ¿Alguien puede ayudarme a escribir un progtwig de python para hacer esto?

mi lista se ve así

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

Me gustaría tener una salida como esta

 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] 

Aquí es una manera simple y agradable utilizando numpys digitalizar :

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

digitalizar, devuelve una matriz con el valor de índice para el contenedor al que pertenece cada elemento.

Esto creará un dictado donde cada valor es una lista de elementos que caben en un contenedor.

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

¿Es esto lo que quieres? (La salida de muestra hubiera sido útil 🙂

 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 

rendimientos

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

Esta pregunta de SO que asigna puntos a los contenedores podría ser útil.

Esto funciona:

 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) 

Huellas dactilares:

 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] 

Cómo funciona:

 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) 

Sugiero un tutorial de Python sobre estas declaraciones.

Binning se puede hacer con 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'] 

Nota: esta función de tecla simple asume que los valores en el iterable están entre -0.0 y -10.0. Considere lambda x: "{:.1f}".format(float(x)) para casos generales.

Consulte también esta publicación para obtener detalles sobre cómo funciona groupby .

Podemos hacer contenedores con more_itertools , una biblioteca de terceros.

Dado

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

Código

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

Detalles

Podemos agrupar por la función de tecla, que definimos para dar formato a los números con una sola precisión, es decir, de -0.213 a -0.2 .

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

Se accede a estos contenedores mediante las teclas definidas por la función de tecla:

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

Accede a todos los contenedores iterando claves:

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

Salida

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

La comprensión de la lista y el desempaquetado es otra opción (ver ejemplo de Código).

Consulte también la documentación de more_itertools para obtener más detalles.