Dada una matriz de números 3 por 3
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 matriz bidimensional que 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
Debe haber una forma mejor, ¿no es así?
Quizás para aclarar: por normalizar quiero decir, la suma de las entradas por fila debe ser uno. Pero creo que eso quedará claro para la mayoría de la gente.

Respuestas:
La transmisión es realmente buena para esto:
row_sums = a.sum(axis=1) new_matrix = a / row_sums[:, numpy.newaxis]row_sums[:, numpy.newaxis]transforma row_sums de ser(3,)a ser(3, 1). Cuando lo hacena / b,aybse transmiten entre sí.Puede obtener más información sobre la transmisión aquí o incluso mejor aquí .
fuente
a.sum(axis=1, keepdims=True)para mantener la dimensión de la columna singleton, que luego puede transmitir sin tener que usarnp.newaxis.np.linalg.normlugar dea.sum!row_sums.reshape(3,1)?Scikit-learn tiene una función de normalización que le permite aplicar varias normalizaciones. El "haz que sume a 1" es la norma L1, y para tomar eso:
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 sumarán 1.
fuente
Creo que esto debería funcionar,
a = numpy.arange(0,27.,3).reshape(3,3) a /= a.sum(axis=1)[:,numpy.newaxis]fuente
En caso de que esté intentando normalizar cada fila de modo que su magnitud sea uno (es decir, la unidad de longitud de una fila es uno o la suma del cuadrado 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]])Verificando:
np.sum( result**2, axis=-1 ) # array([ 1., 1., 1.])fuente
Creo que se puede normalizar la suma de elementos de fila 1 por el siguiente:
new_matrix = a / a.sum(axis=1, keepdims=1). Y la normalización de la columna se puede hacer connew_matrix = a / a.sum(axis=0, keepdims=1). Espero que esto pueda ayudar.fuente
Podrías usar la función numpy incorporada:
np.linalg.norm(a, axis = 1, keepdims = True)fuente
parece que esto también funciona
def normalizeRows(M): row_sums = M.sum(axis=1) return M / row_sumsfuente
También puede usar la transposición de matriz:
fuente
O usando 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 norma unitaria.
fuente
Aquí hay otra forma posible de usar
reshape:a_norm = (a/a.sum(axis=1).reshape(-1,1)).round(3) print(a_norm)O usando
Noneobras también:a_norm = (a/a.sum(axis=1)[:,None]).round(3) print(a_norm)Salida :
array([[0. , 0.333, 0.667], [0.25 , 0.333, 0.417], [0.286, 0.333, 0.381]])fuente
normed_matrix = normalize(input_data, axis=1, norm='l1') print(normed_matrix)donde input_data es el nombre de su matriz 2D
fuente