2012-03-20 14 views
11

Mi pregunta es acerca de una operación de matriz específica que quiero expresar usando numpy.Numpy acumulando una matriz en otra usando la matriz de índice

que tienen una serie de flotadores w y una serie de índices idx de la misma longitud que w y quiero resumir todo lo w con el mismo valor idx y recogerlas en una matriz v. como un bucle, esto se parece a esto:

for i, x in enumerate(w): 
    v[idx[i]] += x 

¿Hay una manera de hacer esto con las operaciones de la matriz? Mi conjetura era v[idx] += w pero eso no funciona, ya que idx contiene el mismo índice varias veces.

Gracias!

+0

Y * atomic * realmente es una descripción inapropiada de lo que quiere hacer. – Constantinius

+0

¿Cómo lo describirías? Espero que el nuevo título sea mejor. –

+1

@Constantinius, Él aceptó una respuesta para todas las preguntas menos una, que tenía una respuesta que, aunque era buena, no abordaba su problema real. Tal vez * usted * debería trabajar para no llamar la atención sobre el aspecto del juego de este sitio. –

Respuesta

15

numpy.bincount se introdujo para este propósito:

tmp = np.bincount(idx, w) 
v[:len(tmp)] += tmp 

creo que a partir del 1.6 también puede pasar un minLength a bincount.

+0

¡Estaba al tanto del bincount, pero no sabía que podía manejar pesas! increíble :) –

+0

genial, casi olvida este pequeño duende pequeño. – nye17

+0

Por favor, siéntete libre de sentirte como mi héroe por el resto del día :) –

4

Este es un comportamiento conocido y, aunque algo desafortunado, no tiene una solución de nivel numpy. (bincount puede usarse para esto si tuerce su brazo.) Hacer el loop usted mismo es realmente su mejor opción.

Tenga en cuenta que el código podría haber sido un poco más clara sin volver a usar el nombre w y sin introducir otra serie de índices, como

for i, w_thing in zip(idx, w): 
    v[i] += w_thing 

Si necesita acelerar este bucle, es posible que tenga para bajar a C. Cython lo hace relativamente fácil.

+0

Aún más simple: 'para i en idx: v [i] + = w [i]'. –

+1

O el excelente 'scipy.weave.inline'. – katrielalex

+0

Sin índices esto debería funcionar, ¿verdad? El código que publicó simplemente hace '' v + w'', ¿verdad? (Si '' v'' es más largo que '' w'' solo se usan los primeros elementos '' len (w) '. Reutilizar' 'w'' fue un error bastante malo, lo siento. –

Cuestiones relacionadas