Read shapes from the right
ValueError. The official broadcasting guide gives the general rules.(2, 2) and quantities shaped (2,), the quantity axis matches the final price axis. If that final axis means assets, each quantity applies down its asset column. A one-dimensional array has no separate row or column orientation: its single axis aligns on the right.Two assets across two scenarios
The following fictional portfolio holds 2 units of asset A and 3 units of asset B in both scenarios. All prices are USD per unit; all resulting values are USD. Asset order is A, B throughout.
import numpy as np
# Rows: scenarios S1, S2. Columns: assets A, B.
# Prices are USD per unit; quantities are units held.
prices = np.array([[100, 200], [110, 180]], dtype=int)
quantities = np.array([2, 3], dtype=int) # asset order: A, B
values = prices * quantities
print(prices.shape, quantities.shape, values.shape)
# (2, 2) (2,) (2, 2)
print(values.tolist())
# [[200, 600], [220, 540]]
print(values.sum(axis=1).tolist())
# [800, 760]axis=1 then combines the asset columns, leaving one portfolio value per scenario: USD 800 in S1 and USD 760 in S2. That reduction is a separate operation from broadcasting. These are position values, not profits or losses.The silent wrong-axis calculation
None inside an index inserts an axis of length 1. Here, quantities[:, None] changes (2,) into (2, 1):wrong_values = prices * quantities[:, None]
print(quantities[:, None].shape)
# (2, 1)
print(wrong_values.tolist())
# [[200, 400], [330, 540]]
print(wrong_values.sum(axis=1).tolist())
# [600, 870]Now the multiplier 2 applies to both assets in S1, while 3 applies to both assets in S2. NumPy accepts the calculation because there happen to be two scenarios and two assets. The code has treated asset quantities as scenario multipliers. The output still has the expected shape, but USD 600 and USD 870 are wrong portfolio values for the stated holdings.
Original fictional example. Rows are scenarios S1 and S2; columns are assets A and B. Prices are USD per unit, quantities are units, and resulting values and totals are USD. Equal axis lengths allow the wrong orientation to run without an error.
quantities[None, :] has shape (1, 2) and preserves the asset-wise multiplication above. A per-scenario multiplier would instead need the scenario axis retained and a singleton asset axis. Check axis meanings and asset ordering alongside shapes; a shape assertion cannot detect an A/B ordering swap.Compact inputs do not guarantee a small result
out argument still allocates its result. An expression that combines many scenarios, assets and parameter settings can create a large output or intermediate array. Estimate those shapes before expanding the calculation.The examples use NumPy arrays. Ordinary Python list multiplication does not provide element-wise array multiplication. Code and outputs were checked with Python 3.14.4 and NumPy 2.5.1.