scikit-learn-extra + NumPy 2: dtype size changed (tested fixes)
pip install scikit-learn-extra today gives 0.3.0 with NumPy 2, and from sklearn_extra.cluster import KMedoids fails with ValueError: numpy.dtype size changed, may indicate binary incompatibility. Building from source does not fix it. Three fixes that worked: numpy<2, install from GitHub main, or switch to the kmedoids package.
1. Fresh install: scikit-learn-extra 0.3.0 + NumPy 2.4
pip install scikit-learn-extra on Python 3.11 resolves to scikit-learn-extra 0.3.0 (the latest release, from 2023), numpy 2.4.6, scikit-learn 1.9.1 and scipy 1.17.1. The 0.3.0 metadata only says numpy>=1.13.3, so nothing stops NumPy 2. The script:
import numpy, sklearn
print("numpy", numpy.__version__, "| scikit-learn", sklearn.__version__)
from sklearn_extra.cluster import KMedoids
import numpy as np
X = np.array([[1, 2], [1, 4], [1, 0], [4, 2], [4, 4], [4, 0]])
km = KMedoids(n_clusters=2, random_state=0).fit(X)
print("labels", km.labels_)
Output:
numpy 2.4.6 | scikit-learn 1.9.1
Traceback (most recent call last):
File "b1.py", line 3, in <module>
from sklearn_extra.cluster import KMedoids
File "site-packages/sklearn_extra/__init__.py", line 1, in <module>
from . import kernel_approximation, kernel_methods # noqa
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/sklearn_extra/kernel_approximation/__init__.py", line 1, in <module>
from ._fastfood import Fastfood
File "site-packages/sklearn_extra/kernel_approximation/_fastfood.py", line 11, in <module>
from ..utils._cyfht import fht2 as cyfht
File "sklearn_extra/utils/_cyfht.pyx", line 1, in init sklearn_extra.utils._cyfht
ValueError: numpy.dtype size changed, may indicate binary incompatibility. Expected 96 from C header, got 88 from PyObject
The 0.3.0 wheels were compiled against NumPy 1.x. Any import from sklearn_extra fails, because the package __init__ loads the Cython module _cyfht first, even if you only want KMedoids.
2. Fix A: pin numpy<2
pip install "numpy<2"
In the same venv this went from numpy 2.4.6 to 1.26.4, kept scikit-learn 1.9.1 and scipy 1.17.1 (both allow it; pip check reported nothing), and the same script ran:
numpy 1.26.4 | scikit-learn 1.9.1
labels [0 0 0 1 1 1]
3. Building 0.3.0 from source does not help
pip install --no-binary scikit-learn-extra scikit-learn-extra==0.3.0 compiled (about 40 s) but failed in a different way. The sdist's pyproject.toml build requirements include oldest-supported-numpy, so it is built against NumPy 1.x again, then run against 2.4.6:
numpy 2.4.6 | scikit-learn 1.9.1
A module that was compiled using NumPy 1.x cannot be run in
NumPy 2.4.6 as it may crash. To support both 1.x and 2.x
versions of NumPy, modules must be compiled with NumPy 2.0.
Some module may need to rebuild instead e.g. with 'pybind11>=2.12'.
If you are a user of the module, the easiest solution will be to
downgrade to 'numpy<2' or try to upgrade the affected module.
We expect that some modules will need time to support NumPy 2.
[... traceback trimmed ...]
ImportError: numpy.core.multiarray failed to import (auto-generated because you didn't call 'numpy.import_array()' after cimporting numpy; use '<void>numpy._import_array' to disable if you are certain you don't need it).
4. Fix B: install from GitHub main
Upstream merged "Add support for numpy 2" (#181) on 2026-09-21, but there has been no PyPI release since 0.3.0. Installing from the repository (needs git and a C compiler):
pip install "scikit-learn-extra @ git+https://github.com/scikit-learn-contrib/scikit-learn-extra"
This built scikit-learn-extra 0.3.0.dev0 at commit da55e27 in about 33 s. With numpy 2.4.6 the same script printed:
numpy 2.4.6 | scikit-learn 1.9.1
labels [0 0 0 1 1 1]
Pin the commit hash (...scikit-learn-extra@da55e27dbbc4c028874ab4f1e1057bd073480ba1) in requirements so your builds stay reproducible.
5. Fix C: only need KMedoids? Use the kmedoids package
The separate kmedoids package (0.5.5, Rust FasterPAM) installed as a prebuilt wheel next to numpy 2.4.6. Its KMedoids defaults to metric="precomputed", so passing raw feature rows like scikit-learn-extra panics:
numpy 2.4.6 | kmedoids 0.5.5
[... traceback trimmed ...]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pyo3_runtime.PanicException: assertion `left == right` failed
left: 6
right: 2
Pass metric="euclidean" (or give it a distance matrix):
import numpy as np, kmedoids
from importlib.metadata import version
print("numpy", np.__version__, "| kmedoids", version("kmedoids"))
X = np.array([[1, 2], [1, 4], [1, 0], [4, 2], [4, 4], [4, 0]])
km = kmedoids.KMedoids(n_clusters=2, metric="euclidean", method="fasterpam", random_state=0).fit(X)
print("labels", km.labels_)
print("medoid rows", km.medoid_indices_)
numpy 2.4.6 | kmedoids 0.5.5
labels [1 1 1 0 0 0]
medoid rows [3 0]
Same clustering, labels swapped (label numbers are arbitrary). Its attributes include labels_ and medoid_indices_; check results on your data before you switch, because the algorithms and defaults (init="random", max_iter=300) are not the same as scikit-learn-extra's.
Other libraries with the same problem: NumPy 2 breaking changes (and old scikit-learn + NumPy 2).
Frequently asked questions
Does scikit-learn-extra support NumPy 2?
Not the PyPI release (0.3.0). GitHub main has NumPy 2 support since 2026-09-21 (#181), not released yet.
Why does building 0.3.0 from source still fail?
Its build requirements pin oldest-supported-numpy, so it compiles against NumPy 1.x again and fails at import on NumPy 2.
Written with AI assistance. Measured on 2026-10-24 on Linux with Python 3.11.17 in fresh uv venvs: scikit-learn-extra 0.3.0 (wheel, sdist build, and git main da55e27), numpy 2.4.6 and 1.26.4, scikit-learn 1.9.1, kmedoids 0.5.5. Scripts ran verbatim; output pasted unedited except shortened paths and marked trims. PlainTables is our extension; scikit-learn-extra and kmedoids are free.