Skip to main content

Python NumPy: How to Divide Each Row by a Vector in NumPy

Row-wise division is common in data normalization and scaling operations. NumPy's broadcasting rules require reshaping 1D vectors to column vectors for proper alignment with 2D matrices.

The Problem

When dividing a matrix by a vector, you need each row divided by a corresponding value:

import numpy as np

matrix = np.array([
[10, 20, 30],
[40, 50, 60]
])

divisors = np.array([10, 5]) # Row 0 ÷ 10, Row 1 ÷ 5

# This fails!
try:
result = matrix / divisors
except ValueError as e:
print(f"Error: {e}")
# Error: operands could not be broadcast together with shapes (2,3) (2,)

Output:

Error: operands could not be broadcast together with shapes (2,3) (2,) 

The shapes don't align for broadcasting because NumPy tries to match from the right.

The Solution: Using np.newaxis

Reshape the divisor vector to a column vector with [:, np.newaxis]:

import numpy as np

matrix = np.array([
[10, 20, 30],
[40, 50, 60]
])

divisors = np.array([10, 5])

# Reshape divisors to column vector (2, 1)
result = matrix / divisors[:, np.newaxis]

print(result)

Output:

[[ 1.  2.  3.]
[ 8. 10. 12.]]

Step-by-Step Breakdown

import numpy as np

matrix = np.array([[10, 20, 30],
[40, 50, 60]])
divisors = np.array([10, 5])

print(f"Matrix shape: {matrix.shape}") # (2, 3)
print(f"Divisors shape: {divisors.shape}") # (2,)

# Reshape divisors to column vector
column_divisors = divisors[:, np.newaxis]
print(f"Column divisors shape: {column_divisors.shape}") # (2, 1)
print(f"Column divisors:\n{column_divisors}")
# [[10]
# [ 5]]

# Now broadcasting works:
# (2, 3) / (2, 1) → (2, 3)
result = matrix / column_divisors
print(f"Result:\n{result}")

Output:

Matrix shape: (2, 3)
Divisors shape: (2,)
Column divisors shape: (2, 1)

Understanding Broadcasting

Broadcasting aligns shapes from the right. For row-wise operations, the divisor needs a trailing dimension of 1:

ArrayShapeAlignment
matrix(2, 3)2 × 3
divisors(2,)? × 2
divisors[:, np.newaxis](2, 1)2 × 1
import numpy as np

# Visualizing the broadcast
matrix = np.array([[10, 20, 30],
[40, 50, 60]])

divisors = np.array([[10], # Broadcasts across row 0
[5]]) # Broadcasts across row 1

print("Matrix:")
print(matrix)

print("\nDivisors:")
print(divisors)

result = matrix / divisors # Broadcasting happens here

print("\nResult:")
print(result)

# Effectively becomes:
# [[10, 20, 30] [[10, 10, 10] [[ 1., 2., 3.]
# [40, 50, 60]] / [ 5, 5, 5]] = [ 8., 10., 12.]]

Output:

Matrix:
[[10 20 30]
[40 50 60]]

Divisors:
[[10]
[ 5]]

Result:
[[ 1. 2. 3.]
[ 8. 10. 12.]]

Alternative: Using reshape()

reshape(-1, 1) achieves the same result:

import numpy as np

matrix = np.array([[10, 20, 30],
[40, 50, 60]])
divisors = np.array([10, 5])

# Using reshape
result = matrix / divisors.reshape(-1, 1)

print(result)

Output:

[[ 1.  2.  3.]
[ 8. 10. 12.]]

Alternative: Using None

None is an alias for np.newaxis:

import numpy as np

matrix = np.array([[10, 20, 30],
[40, 50, 60]])
divisors = np.array([10, 5])

# None works the same as np.newaxis
result = matrix / divisors[:, None]

print(result)

Output:

[[ 1.  2.  3.]
[ 8. 10. 12.]]
tip

Use None for brevity in quick scripts, but np.newaxis is more explicit and readable in production code.

Row-wise vs Column-wise Operations

Understanding the difference helps avoid confusion:

import numpy as np

matrix = np.array([[10, 20, 30],
[40, 50, 60]])

row_divisors = np.array([10, 5]) # 2 values (one per row)
col_divisors = np.array([10, 20, 30]) # 3 values (one per column)

# Row-wise: divide each row by its corresponding value
row_result = matrix / row_divisors[:, np.newaxis]
print("Row-wise division:")
print(row_result)

# Column-wise: divide each column by its corresponding value
col_result = matrix / col_divisors # No reshape needed!
print("\nColumn-wise division:")
print(col_result)

Output:

Row-wise division:
[[ 1. 2. 3.]
[ 8. 10. 12.]]

Column-wise division:
[[1. 1. 1. ]
[4. 2.5 2. ]]

Practical Examples

Normalizing Rows by Their Sum

import numpy as np

data = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])

# Calculate sum of each row
row_sums = data.sum(axis=1)
print(f"Row sums: {row_sums}")

# Normalize each row
normalized = data / row_sums[:, np.newaxis]
print("Normalized rows:")
print(normalized)

# Verify rows sum to 1
print(f"Row sums after normalization: {normalized.sum(axis=1)}")

Output:

Row sums: [ 6 15 24]
Normalized rows:
[[0.16666667 0.33333333 0.5 ]
[0.26666667 0.33333333 0.4 ]
[0.29166667 0.33333333 0.375 ]]
Row sums after normalization: [1. 1. 1.]

Dividing by Row Maximum

import numpy as np

data = np.array([
[10, 20, 30],
[5, 15, 25],
[100, 200, 150]
])

# Get max of each row
row_max = data.max(axis=1)
print(f"Row max: {row_max}")

# Scale each row to [0, 1] range
scaled = data / row_max[:, np.newaxis]
print("Scaled by row max:")
print(scaled)

Output:

Row max: [ 30  25 200]
Scaled by row max:
[[0.33333333 0.66666667 1. ]
[0.2 0.6 1. ]
[0.5 1. 0.75 ]]

Z-Score Normalization by Row

import numpy as np

data = np.array([
[10, 20, 30],
[100, 200, 300],
[5, 10, 15]
])

# Calculate row means and standard deviations
row_means = data.mean(axis=1)
row_stds = data.std(axis=1)

# Z-score normalize each row
z_scores = (data - row_means[:, np.newaxis]) / row_stds[:, np.newaxis]
print("Z-scores by row:")
print(z_scores)

Output:

Z-scores by row:
[[-1.22474487 0. 1.22474487]
[-1.22474487 0. 1.22474487]
[-1.22474487 0. 1.22474487]]

Other Row-wise Operations

The same pattern works for other operations:

import numpy as np

matrix = np.array([[10, 20, 30],
[40, 50, 60]])
row_values = np.array([5, 10])

# Row-wise addition
print(matrix + row_values[:, np.newaxis])

# Row-wise subtraction
print(matrix - row_values[:, np.newaxis])

# Row-wise multiplication
print(matrix * row_values[:, np.newaxis])

Output:

[[15 25 35]
[50 60 70]]
[[ 5 15 25]
[30 40 50]]
[[ 50 100 150]
[400 500 600]]

Quick Reference

OperationVector ShapeCode
Divide each row(n_rows,)(n_rows, 1)matrix / vec[:, np.newaxis]
Divide each column(n_cols,)matrix / vec (no reshape)
Scalar division()matrix / scalar

Summary

Use vector[:, np.newaxis] or vector.reshape(-1, 1) to convert a 1D array into a column vector for row-wise operations.

This aligns the shapes for NumPy broadcasting, allowing each row to be divided (or multiplied, added, etc.) by its corresponding value in the vector.