Home > Blockchain >  NumPy / Python - Scalars to rows broadcasting in an element-wise multiplicaiton
NumPy / Python - Scalars to rows broadcasting in an element-wise multiplicaiton

Time:10-26

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).

  • Related