Encontrar elementos en una matriz en función de una segunda matriz

Tengo dos matrices A y B:

A=array([[ 5.,  5.,  5.],
         [ 8.,  9.,  9.]])
B=array([[ 1.,  1.,  2.],
         [ 3.,  2.,  1.]])

En cualquier lugar hay un "1" en B Quiero sumar las mismas ubicaciones de fila y columna en A.

Entonces, por ejemplo, para este, la respuesta sería 5+5+9=10

Me gustaría que esto continuara durante 2,3....n (todos los valores únicos en B)

Así que para los 2... sería 9+5=14 y para los 3 sería 8

Encontré los valores únicos usando:

numpy.unique(B)

Me doy cuenta de que esto requiere varios pasos, pero realmente no puedo entender el uso de la matriz de índice para sumar esas ubicaciones en otra matriz.

preguntado el 27 de julio de 12 a las 18:07

Creo que quieres decir 5+5+9=19 :-)-

5 Respuestas

Para cada valor único x, tu puedes hacer

A[B == x].sum()

Ejemplo:

>>> A[B == 1.0].sum()
19.0

Respondido 27 Jul 12, 18:07

Creo que el numpy.bincount es lo que quieres Si B es una matriz de pequeños enteros como en su ejemplo, puede hacer algo como esto:

import numpy
A = numpy.array([[ 5.,  5.,  5.],
                 [ 8.,  9.,  9.]])
B = numpy.array([[ 1,  1,  2],
                 [ 3,  2,  1]])
print numpy.bincount(B.ravel(), weights=A.ravel())
# [  0.  19.  14.   8.]

o si B tiene cualquier cosa menos enteros pequeños, puede hacer algo como esto

import numpy
A = numpy.array([[ 5.,  5.,  5.],
                 [ 8.,  9.,  9.]])
B = numpy.array([[ 1.,  1.,  2.],
                 [ 3.,  2.,  1.]])
uniqB, inverse = numpy.unique(B, return_inverse=True)
print uniqB, numpy.bincount(inverse, weights=A.ravel())
# [ 1.  2.  3.] [ 19.  14.   8.]

Respondido 27 Jul 12, 22:07

Eso es exactamente lo que estaba buscando, pero por alguna razón sigo recibiendo "la matriz no se puede convertir de manera segura al tipo requerido". ¿Tiene alguna idea de por qué seguiría recibiendo este error? ¡Gracias! @Bago- eric escobar

No importa, creo que es porque es un flotante y no un int. Sin embargo, realmente me gustó esta salida porque necesito que tenga un "0" si no hay coincidencias para que el espacio entre columnas no se salga de control. eric escobar

Siempre puede hacer numpy.bincount(B.ravel().astype('int'), weights=A.ravel()) si tiene una matriz de flotantes que sabe que se pueden convertir de forma segura a int. - bi-rico

[(val, np.sum(A[B==val])) for val in np.unique(B)] le da una lista de tuplas donde el primer elemento es uno de los valores únicos en B, y el segundo elemento es la suma de los elementos en A donde el valor correspondiente en B es ese valor.

>>> [(val, np.sum(A[B==val])) for val in np.unique(B)]
[(1.0, 19.0), (2.0, 14.0), (3.0, 8.0)]

La clave es que puedes usar A[B==val] para acceder a elementos en A en posiciones donde B es igual a val.

Editar: si solo quieres las sumas, solo hazlo [np.sum(A[B==val]) for val in np.unique(B)].

Respondido 28 Jul 12, 01:07

¿Cómo obtendría la salida para ser: [ 0. 19. 14. 8.] ¿Y esto también pondría 0 donde no había nada en la matriz B? - eric escobar

@EricEscobar, mira mi respuesta editada. Si desea 0 para los elementos que faltan en B, debe ser más específico. Obviamente, hay una cantidad infinita de valores que no están presentes en B, por lo que debe decir qué valores espera que estén en B. - BrenBarn

Usaría matrices enmascaradas numpy. Estas son matrices numpy estándar con una máscara asociada que bloquea ciertos valores. El proceso es bastante sencillo, cree una matriz enmascarada usando

numpy.ma.masked_array(data, mask)

donde la máscara se genera usando una función enmascarada

mask = numpy.ma.masked_not_equal(B, 1).mask

y los datos son A

for i in numpy.unique(B):
    print numpy.ma.masked_array(A, numpy.ma.masked_not_equal(B, i).mask).sum()

19.0
14.0
8.0

Respondido 27 Jul 12, 19:07

encontré una vieja pregunta aquí

uno de los https://www.youtube.com/watch?v=xB-eutXNUMXJtA&feature=youtu.be

def sum_by_group(values, groups):
 order = np.argsort(groups)
 groups = groups[order]
 values = values[order]
 values.cumsum(out=values)
 index = np.ones(len(groups), 'bool')
 index[:-1] = groups[1:] != groups[:-1]
 values = values[index]
 groups = groups[index]
 values[1:] = values[1:] - values[:-1]
 return values, groups

en su caso, puede aplanar su matriz

aflat = A.flatten()
bflat = B.flatten()
sum_by_group(aflat, bflat)

contestado el 23 de mayo de 17 a las 12:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.