Me gustaría tener la norma de una Colección de la matriz. Más específicamente, estoy buscando una versión equivalente de esta función

def normalize(v):
    norm = np.linalg.norm(v)
    if norm == 0: 
       return v
    return v / norm

Hay algo como que en skearn o numpy?

Esta función funciona en una situación en la que v es el vector 0.

¿Qué hay de malo con lo que has escrito?
Si esto es realmente una preocupación, usted debe comprobar por norma < epsilon, donde epsilon es una pequeña tolerancia. Además, yo no me silenciosamente pase atrás de una norma vector cero, me gustaría raise una excepción!
mi función funciona, pero me gustaría saber si hay algo en el interior de python más común de la biblioteca. Estoy escribiendo de máquinas diferentes funciones de aprendizaje y me gustaría evitar a definir demasiado nuevas funciones para hacer el código más claro y legible
Una posible preocupación es que, en los actuales NumPy, np.linalg.norm es es lento. Me puso un parche para la próxima versión, pero antes de que se acabe, me gustaría evitar esta función si la velocidad es un problema.
Yo hice un par de pruebas rápidas y he encontrado que x/np.linalg.norm(x) no fue mucho más lento (unos 15-20%) que x/np.sqrt((x**2).sum()) en numpy 1.15.1 en una CPU.

OriginalEl autor Donbeo | 2014-01-09

7 Comentarios

  1. 104

    Si usted está usando scikit-learn puede utilizar sklearn.preprocesamiento.normalizar:

    import numpy as np
    from sklearn.preprocessing import normalize
    
    x = np.random.rand(1000)*10
    norm1 = x / np.linalg.norm(x)
    norm2 = normalize(x[:,np.newaxis], axis=0).ravel()
    print np.all(norm1 == norm2)
    # True
    Gracias por la respuesta, pero son usted seguro de que sklearn.preprocesamiento.normalizar funciona también con el vector de la forma=(n, a) o (n,1) ? Estoy teniendo algunos problemas con esta biblioteca
    normalize requiere una entrada 2D. Usted puede pasar el axis= argumento para especificar si desea aplicar la normalización a través de las filas o columnas de la matriz de entrada.
    Tenga en cuenta que la ‘norma’ argumento de la función de normalización puede ser ‘l1’ o ‘l2’ y el valor predeterminado es ‘l2’. Si usted quiere que su vector suma a 1 (por ejemplo, una distribución de probabilidad) se debe utilizar la norma=’l1′ en la función de normalización.
    También tenga en cuenta que np.linalg.norm(x) calcula ‘l2’ norma por defecto. Si usted quiere que su vector de la suma de a 1 se debe utilizar np.linalg.norm(x, ord=1)

    OriginalEl autor ali_m

  2. 31

    Yo estaría de acuerdo en que era agradable si tal función fue parte de las baterías incluidas. Pero no es, hasta donde yo sé. Aquí hay una versión para ejes arbitrarios, y dando un rendimiento óptimo.

    import numpy as np
    
    def normalized(a, axis=-1, order=2):
        l2 = np.atleast_1d(np.linalg.norm(a, order, axis))
        l2[l2==0] = 1
        return a / np.expand_dims(l2, axis)
    
    A = np.random.randn(3,3,3)
    print(normalized(A,0))
    print(normalized(A,1))
    print(normalized(A,2))
    
    print(normalized(np.arange(3)[:,None]))
    print(normalized(np.arange(3)))
    Yo no profundamente prueba de la ali_m solución, pero en algunos caso sencillo en el que parece estar funcionando. Hay situtions donde su función no es mejor?
    No sé, pero funciona a través de ejes arbitrarios, y tenemos el control explícito sobre lo que sucede para la longitud 0 vectores.
    Muy bonito! Esto se debe en numpy — aunque el orden debe, probablemente, llegar antes de eje, en mi opinión.
    La curiosidad de entender por qué order=2 elegido por encima de los demás?
    Debido a que la Euclidiana/pythagoran norma pasa a ser el más frecuentemente utilizado uno; ¿no estás de acuerdo?

    OriginalEl autor Eelco Hoogendoorn

  3. 13

    Puede especificar ord para obtener la L1 norma.
    Para evitar el cero de la división I de uso eps, pero que quizás no es muy grande.

    def normalize(v):
        norm=np.linalg.norm(v, ord=1)
        if norm==0:
            norm=np.finfo(v.dtype).eps
        return v/norm
    la normalización de [inf, 1, 2] rendimientos [nan, 0, 0], pero no debería ser [1, 0, 0]?

    OriginalEl autor Eduard Feicho

  4. 4

    Si usted tiene datos multidimensionales y desea que cada uno de los ejes normalizados a sí mismo:

    def normalize(d):
        # d is a (n x dimension) np array
        d -= np.min(d, axis=0)
        d /= np.ptp(d, axis=0)
        return d

    Utiliza numpys pico a pico función.

    OriginalEl autor Jaden Travnik

  5. 4

    Esto también podría funcionar para usted

    import numpy as np
    normalized_v = v / np.sqrt((np.sum(v**2)))

    pero falla cuando v tiene una longitud de 0.

    OriginalEl autor mk18

  6. 2

    También existe la función unit_vector() para normalizar los vectores en el popular transformaciones módulo por Christoph Gohlke:

    import transformations as trafo
    import numpy as np
    
    data = np.array([[1.0, 1.0, 0.0],
                     [1.0, 1.0, 1.0],
                     [1.0, 2.0, 3.0]])
    
    print(trafo.unit_vector(data, axis=1))

    OriginalEl autor Joe

  7. 1

    Si desea normalizar n dimensional función de los vectores almacenados en 3D tensor, también se podría utilizar PyTorch:

    import numpy as np
    from torch import FloatTensor
    from torch.nn.functional import normalize
    
    vecs = np.random.rand(3, 16, 16, 16)
    norm_vecs = normalize(FloatTensor(vecs), dim=0, eps=1e-16).numpy()

    OriginalEl autor max0r

Dejar respuesta

Please enter your comment!
Please enter your name here