py-06-numpy-distances
0.667
Challenge · difficulty 3/5
# Pairwise distances (numpy)
Implement **`solution.py`** with:
```python
import numpy as np
def pairwise_distances(points: np.ndarray) -> np.ndarray:
...
```
`points` is a 2-D array of shape `(n, d)` (n points in d dimensions). Return an `(n, n)`
array where entry `[i, j]` is the Euclidean distance between point `i` and point `j`.
- The result must be a NumPy array (`np.ndarray`), symmetric, with a zero diagonal.
- Use NumPy vectorization (no Python `for` loops over point pairs).
- Example: for `[[0, 0], [3, 4]]` the result is `[[0, 5], [5, 0]]`.
tests/test_distances.py
import numpy as np
from solution import pairwise_distances
def test_simple():
pts = np.array([[0.0, 0.0], [3.0, 4.0]])
d = pairwise_distances(pts)
assert isinstance(d, np.ndarray)
assert d.shape == (2, 2)
np.testing.assert_allclose(d, [[0.0, 5.0], [5.0, 0.0]], atol=1e-9)
def test_symmetric_zero_diagonal():
rng = np.random.default_rng(0)
pts = rng.standard_normal((6, 3))
d = pairwise_distances(pts)
assert d.shape == (6, 6)
np.testing.assert_allclose(d, d.T, atol=1e-9)
np.testing.assert_allclose(np.diag(d), np.zeros(6), atol=1e-9)
def test_matches_bruteforce():
rng = np.random.default_rng(42)
pts = rng.standard_normal((5, 4))
d = pairwise_distances(pts)
for i in range(5):
for j in range(5):
expected = np.sqrt(((pts[i] - pts[j]) ** 2).sum())
assert abs(d[i, j] - expected) < 1e-9
Proposed solution
```python
import numpy as np
def pairwise_distances(points: np.ndarray) -> np.ndarray:
sq_norms = np.sum(points**2, axis=1)
dist_sq = sq_norms[:, np.newaxis] + sq_norms[np.newaxis, :] - 2 * (points @ points.T)
return np.sqrt(np.maximum(dist_sq, 0))
```Test output (stdout)
.F. [100%]
=================================== FAILURES ===================================
_________________________ test_symmetric_zero_diagonal _________________________
def test_symmetric_zero_diagonal():
rng = np.random.default_rng(0)
pts = rng.standard_normal((6, 3))
d = pairwise_distances(pts)
assert d.shape == (6, 6)
np.testing.assert_allclose(d, d.T, atol=1e-9)
> np.testing.assert_allclose(np.diag(d), np.zeros(6), atol=1e-9)
E AssertionError:
E Not equal to tolerance rtol=1e-07, atol=1e-09
E
E Mismatched elements: 1 / 6 (16.7%)
E Mismatch at index:
E [5]: 1.4901161193847656e-08 (ACTUAL), 0.0 (DESIRED)
E Max absolute difference among violations: 1.49011612e-08
E Max relative difference among violations: inf
E ACTUAL: array([0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00,
E 0.000000e+00, 1.490116e-08])
E DESIRED: array([0., 0., 0., 0., 0., 0.])
test_distances.py:19: AssertionError
=========================== short test summary info ============================
FAILED test_distances.py::test_symmetric_zero_diagonal - AssertionError:
1 failed, 2 passed in 0.07s