I am searching for an elegant solution for multiplying each i-th row of the matrix by the corresponding i-th value of the vector (element-wise). This can be done by iterating the rows of the matrix and the vector of scalars at the same time (as illustrated in the code snippet below) - but I am wondering whether there is a more elegant solution to that (perhaps using NDArray methods).
def normalise(matrix):
norm_c = 1.00 / matrix.sum(axis=1)
for i in range(len(matrix)):
matrix[i] = matrix[i] * norm_c[i]
return matrix
The problem popped out when I was writing a code to check if values in each row are summing up to 1. If they don't, we can simply obtain a scalar which would allow us to rescale each row correspondingly by one-liner:
norm_c = 1.00 / matrix.sum(axis=1)
Which will return an array of length equal to the number of rows in the original matrix. However, to rescale the original matrix, we must perform a scalar * array multiplication:
for i in range(len(matrix)):
matrix[i] = matrix[i] * norm_c[i]
However, I feel that there must be a more elegant solution to that problem - one which does not require employing a basic for a loop - but I can't just fine one.
CodePudding user response:
You can use plain broadcasting
matrix / matrix.sum(axis=1)[:, None]
or alternatively the maybe more intuitive einsum
:
np.einsum('ij,i->ij', matrix, 1/matrix.sum(axis=1))
CodePudding user response:
Thank you for answering! I forgot that the matrix.sum(axis=1) will yield an array of a shape (m,) not (m, 1) -> thus, broadcasting failed in the case when the (n, m) matrix was multiplied by the (n,) array. Thus, the solution provided by @flawr works perfectly, as the array is correctly broadcasted to each of the rows (without raising the broadcasting error).