Lista de comprensión de Python para Numpy

Estoy buscando un método de comprensión de listas o similar en Numpy para eliminar el uso de un bucle for, por ejemplo. index_values ​​es una lista de listas del diccionario Python (cada lista contiene un número diferente de valores de índice) y s es un vector numpy:

for i in range(33): s[index_values[i]] += 4.1 

¿Hay algún método disponible que permita eliminar el for-loop?

No entiendo completamente qué tipo de objeto es index_values . Pero si se tratara de un ndarray , o se podría convertir en un ndarray , podría hacer esto:

 >>> s = numpy.arange(20) >>> index_values = (numpy.random.random((3, 3)) * 20).astype('i') >>> s[index_values] = 4 >>> s array([ 0, 1, 4, 4, 4, 5, 6, 4, 8, 4, 4, 11, 12, 13, 4, 15, 4, 4, 4, 19]) 

Edit: Pero parece que no funcionará en este caso. Sobre la base de sus ediciones y comentarios, aquí hay un método que creo podría funcionar para usted. Una lista aleatoria de listas con longitudes variables …

 >>> index_values = [list(range(x, x + random.randrange(1, 5))) ... for x in [random.randrange(0,50) for y in range(33)]] 

… no es difícil de convertir en una matriz:

 >>> index_value_array = numpy.fromiter(itertools.chain(*index_values), dtype='i') 

Si conoce la longitud de la matriz, especifique el count para un mejor rendimiento:

 >>> index_value_array = numpy.fromiter(itertools.chain(*index_values), dtype='i', count=83) 

Como su edición indica que desea un comportamiento similar al histogtwig, la indexación simple no funcionará, como lo señaló Robert Kern. Así que usa numpy.histogram :

 >>> hist = numpy.histogram(index_value_array, bins=range(0, 51)) 

histogram se construye realmente para los histogtwigs de punto flotante. Esto significa que los contenedores deben ser un poco más grandes de lo esperado porque el último valor está incluido en el último bin, por lo que 48 y 49 estarían en el mismo bin si utilizáramos el range(0, 50) más intuitivo range(0, 50) . El resultado es una tupla con una matriz de n recuentos y una matriz de n + 1 bordes de bin:

 >>> hist (array([2, 2, 1, 2, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 5, 5, 5, 3, 3, 3, 3, 3, 2, 1, 0, 2, 3, 3, 1, 0, 2, 3, 2, 2, 2, 3, 2, 1, 1, 2, 2, 2, 0, 0, 0, 1, 0]), array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50])) 

Ahora podemos escalar los conteos en un factor de 4.1 y realizar la sum de vectores:

 >>> s = numpy.arange(50, dtype='f') >>> hist[0] * 4.1 + s array([ 8.2, 9.2, 6.1, 11.2, 8.1, 5. , 6. , 7. , 12.1, 13.1, 14.1, 15.1, 16.1, 13. , 18.1, 19.1, 20.1, 37.5, 38.5, 39.5, 32.3, 33.3, 34.3, 35.3, 36.3, 33.2, 30.1, 27. , 36.2, 41.3, 42.3, 35.1, 32. , 41.2, 46.3, 43.2, 44.2, 45.2, 50.3, 47.2, 44.1, 45.1, 50.2, 51.2, 52.2, 45. , 46. , 47. , 52.1, 49. ]) 

No tengo idea de si esto se ajusta a sus propósitos, pero parece ser un buen enfoque, y probablemente debería suceder a una velocidad cercana a la c, ya que solo utiliza el numpy y los itertools .

Qué pasa:

 s[reduce(lambda x,y: x+y, [index_values[x] for x in range(33)], [])] = 4.1