A 2-row × 3-column grid reduced two ways: column sums (collapsing rows) and row means (collapsing columns). The naive version uses two separate loops — one iterating over column indices, one over rows — making the direction of each reduction explicit before the replay.

By hand

With NumPy

a.sum(axis=0) collapses along axis 0 (rows), producing one sum per column with shape (3,). a.mean(axis=1) collapses along axis 1 (columns), producing one mean per row with shape (2,). The snapshot shows both result shapes next to the input shape.

naive.py
grid = [[1, 2, 3], [4, 5, 6]]
cols = len(grid[0])
col_sums = []
for j in range(cols):
    s = 0
    for row in grid:
        s += row[j]
    col_sums.append(s)
row_means = []
for row in grid:
    row_means.append(round(sum(row) / len(row), 2))
print('RESULT:', (col_sums, row_means))
library.py
import numpy as np

grid = [[1, 2, 3], [4, 5, 6]]
a = np.array(grid)
col_sums = a.sum(axis=0)
row_means = a.mean(axis=1)
print('shape:', a.shape, 'dtype:', a.dtype)
print(
    'col_sums: shape:', col_sums.shape,
    'dtype:', col_sums.dtype,
    'values:', col_sums.tolist(),
)
print(
    'row_means: shape:', row_means.shape,
    'dtype:', row_means.dtype,
    'values:', row_means.tolist(),
)
print('RESULT:', (col_sums.tolist(), row_means.tolist()))
shape: (2, 3) dtype: int64
col_sums: shape: (3,) dtype: int64 values: [5, 7, 9]
row_means: shape: (2,) dtype: float64 values: [2.0, 5.0]
RESULT: ([5, 7, 9], [2.0, 5.0])

Implementation notes

  • axis=0 means "reduce along axis 0" — collapse rows. A (2, 3) array summed with axis=0 loses the first dimension, yielding (3,): one value per column.
  • axis=1 means "reduce along axis 1" — collapse columns. A (2, 3) array averaged with axis=1 loses the second dimension, yielding (2,): one value per row.
  • mean promotes the dtype to float64 even when the input is integer. sum keeps the integer dtype.
  • The column-centering in center-columns used a.mean(axis=0) to get one mean per column — the same axis-0 rule, just applied to mean instead of sum.
  • Shape, dtype, and values are shown explicitly here because ndarray.__repr__ output varies with NumPy version and print options.