Dado 3 veces 3 numpy matriz

a = numpy.arange(0,27,3).reshape(3,3)

# array([[ 0,  3,  6],
#        [ 9, 12, 15],
#        [18, 21, 24]])

Para normalizar las filas de la 2-dimensiones de la matriz pensé

row_sums = a.sum(axis=1) # array([ 9, 36, 63])
new_matrix = numpy.zeros((3,3))
for i, (row, row_sum) in enumerate(zip(a, row_sums)):
    new_matrix[i,:] = row / row_sum

Que debe haber una mejor manera, ¿no?

Tal vez a clearify: Por la normalización quiero decir, la suma de las entradas por cada fila debe ser uno. Pero creo que va a ser claro para la mayoría de la gente.

  • Cuidado, «normalizar» normalmente significa que la suma de cuadrados de los componentes es uno. Su definición no será claro para la mayoría de la gente;)
InformationsquelleAutor Aufwind | 2012-01-18

10 Comentarios

  1. 122

    De radiodifusión es realmente bueno para esto:

    row_sums = a.sum(axis=1)
    new_matrix = a / row_sums[:, numpy.newaxis]

    row_sums[:, numpy.newaxis] remodela row_sums de ser (3,) a ser (3, 1). Al hacer a /b, a y b se transmiten uno contra el otro.

    Usted puede aprender más acerca de de radiodifusión aquí o incluso mejor aquí.

    • Esto se puede simplificar aún más el uso de a.sum(axis=1, keepdims=True) para mantener el singleton dimensión de columna, que puede difusión a lo largo sin tener que utilizar np.newaxis.
    • lo que si alguno de los row_sums es cero?
    • en ese caso, la normalización de la fila suma en realidad no tiene mucho sentido!
    • Esta es la respuesta correcta para la pregunta como se indicó anteriormente – pero si una normalización en el sentido usual de la palabra que se desea, utilizar np.linalg.norm en lugar de a.sum!
    • es esta preferido row_sums.reshape(3,1) ?
    • No es tan robusto desde la fila suma puede ser 0.
    • Si un vector está normalizado, debe tener una unidad de la norma, el uso de un / row_sums[:, numpy.newaxis] realmente no es garantía de una unidad de la norma.
    • Hay muchas definiciones de «unidad de la norma», echa un vistazo a la ord argumento a colección de normas de función. Ord 1 normas son a menudo útiles y el OP le preguntó específicamente acerca de la normalización con respecto a esta norma, pero por supuesto puede reemplazar el denominador con el más apropiado de la norma para su aplicación.
    • Es este el mismo que MinMaxNorm o ¿cuál es el nombre de esta normalización?

  2. 85

    Scikit-learn tiene una función de normalización que permite aplicar diferentes normalizaciones. El «hacer que se suma a 1» es la norma L1, y a tomar que hacer:

    from sklearn.preprocessing import normalize
    matrix = numpy.arange(0,27,3).reshape(3,3).astype(numpy.float64)
    
    #array([[  0.,   3.,   6.],
    #   [  9.,  12.,  15.],
    #   [ 18.,  21.,  24.]])
    
    normed_matrix = normalize(matrix, axis=1, norm='l1')
    
    #[[ 0.          0.33333333  0.66666667]
    #[ 0.25        0.33333333  0.41666667]
    #[ 0.28571429  0.33333333  0.38095238]]

    Ahora sus filas se suma a 1.

  3. 9

    Creo que esto debería funcionar,

    a = numpy.arange(0,27.,3).reshape(3,3)
    
    a /=  a.sum(axis=1)[:,numpy.newaxis]
    • bueno. nota el cambio de dtype a arange, anexando el punto decimal a 27.
  4. 3

    En caso de que usted está tratando de normalizar cada fila de tal forma que su magnitud es uno (es decir, una fila de la unidad de longitud es uno o la suma de los cuadrados de cada elemento en una fila es uno):

    import numpy as np
    
    a = np.arange(0,27,3).reshape(3,3)
    
    result = a / np.linalg.norm(a, axis=-1)[:, np.newaxis]
    # array([[ 0.        ,  0.4472136 ,  0.89442719],
    #        [ 0.42426407,  0.56568542,  0.70710678],
    #        [ 0.49153915,  0.57346234,  0.65538554]])

    Verificación:

    np.sum( result**2, axis=-1 )
    # array([ 1.,  1.,  1.]) 
    • Eje no parece ser un parámetro para np.linalg.norma (más?).
    • en particular, esto corresponde a la norma l2 (donde como filas sumar a 1 corresponde a la norma l1)
  5. 1

    parece que esto también funciona

    def normalizeRows(M):
        row_sums = M.sum(axis=1)
        return M / row_sums
  6. 0

    O utilizando la función lambda, como

    >>> vec = np.arange(0,27,3).reshape(3,3)
    >>> import numpy as np
    >>> norm_vec = map(lambda row: row/np.linalg.norm(row), vec)

    cada vector de vec tendrá una unidad de la norma.

  7. 0

    Creo que se puede normalizar los elementos de fila suma de a 1 por esto:
    new_matrix = a /a.sum(axis=1, keepdims=1).
    Y la columna de la normalización se puede hacer con new_matrix = a /a.sum(axis=0, keepdims=1). Espero que esto puede hep.

  8. 0
    normed_matrix = normalize(input_data, axis=1, norm='l1')
    print(normed_matrix)

    donde input_data es el nombre de su matriz 2D

Dejar respuesta

Please enter your comment!
Please enter your name here