Getting started¶
Install with uv add numpy-vector-store or
python -m pip install numpy-vector-store. The only runtime dependency is NumPy.
Python 3.11–3.14 are tested, and the minimum NumPy version is 1.23.2.
Bring your own embeddings¶
The library takes vectors you already have. Generate document and query
embeddings with the same model and use its output width as dimensions.
The store does not call an embedding API, split documents, or download models.
add() accepts a two-dimensional real-valued array-like input with shape
(rows, dimensions). Even one vector needs an outer row dimension:
from numpy_vector_store import VectorStore
store = VectorStore[str](dimensions=3)
store.add([[1.0, 0.0, 0.0]], ["one row"])
Vectors become float32. Values must remain finite after conversion; NaN,
infinity, overflow to infinity, and complex inputs are rejected. With the
default normalize=True, zero vectors are also rejected.
Keep metadata in your application¶
Supply one metadata payload per vector row. A payload can be a dict, dataclass, tuple, list, string, integer ID, or another Python object. A tuple or list payload remains one opaque row value. A NumPy metadata array must be one-dimensional.
VectorStore[TMetadata] carries your payload type through get() and search
results. The type parameter does not validate or transform metadata at runtime.
Use application identifiers as payloads if you keep the full records elsewhere.
Keep any external metadata table aligned with the store's row order.
Search and read results¶
The complete quick start is runnable as written.
A search query is one-dimensional, with exactly dimensions real values.
All three metric methods return list[VectorHit[TMetadata]]:
| Field | Meaning |
|---|---|
index |
Original zero-based store row index |
value |
Cosine similarity, dot product, or Euclidean distance |
metadata |
Your payload for that row |
top_k is a positive integer and defaults to 10. You may receive fewer hits
when fewer rows qualify, or an empty list when no rows qualify. Search validates
its arguments even when the store or selected row set is empty.
Use get(index) to retrieve
one row without searching. It returns (vector_copy, metadata) or None for
an integer outside the current row range. len(store) gives the active row count.
Grow or clear a store¶
Repeated add() calls append in insertion order and reuse private capacity.
Batch your inputs when they already arrive together to reduce per-call overhead.
clear() removes all active rows and releases the store's reserved capacity;
it retains the dimensions, normalization mode, and archive binding.
Mutation does not save automatically. Continue with search and filtering, persistence, or the state ownership rules.