pgvector 0.5.0__tar.gz → 0.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pgvector-0.5.0 → pgvector-0.5.1}/PKG-INFO +1 -1
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/bit.py +6 -7
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sparsevec.py +16 -3
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector.egg-info/PKG-INFO +1 -1
- {pgvector-0.5.0 → pgvector-0.5.1}/pyproject.toml +1 -1
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_sparse_vector.py +11 -1
- {pgvector-0.5.0 → pgvector-0.5.1}/LICENSE.txt +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/README.md +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/__init__.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/_utils.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/asyncpg/__init__.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/asyncpg/register.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/__init__.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/bit.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/extensions.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/functions.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/halfvec.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/indexes.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/sparsevec.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/vector.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/halfvec.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/peewee/__init__.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/peewee/bit.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/peewee/halfvec.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/peewee/sparsevec.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/peewee/vector.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/pg8000/__init__.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/pg8000/register.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/__init__.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/bit.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/halfvec.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/register.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/sparsevec.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/vector.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg2/__init__.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg2/halfvec.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg2/register.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg2/sparsevec.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg2/vector.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/py.typed +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/__init__.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/bit.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/functions.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/halfvec.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/sparsevec.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/vector.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/vector.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector.egg-info/SOURCES.txt +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector.egg-info/dependency_links.txt +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/pgvector.egg-info/top_level.txt +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/setup.cfg +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_asyncpg.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_bit.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_django.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_half_vector.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_peewee.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_pg8000.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_psycopg.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_psycopg2.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_sqlalchemy.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_sqlmodel.py +0 -0
- {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_vector.py +0 -0
|
@@ -13,7 +13,7 @@ class Bit:
|
|
|
13
13
|
|
|
14
14
|
def __init__(
|
|
15
15
|
self,
|
|
16
|
-
value: bytes | str | list[bool] | np.ndarray[tuple[int, ...], np.dtype[np.
|
|
16
|
+
value: bytes | str | list[bool] | np.ndarray[tuple[int, ...], np.dtype[np.bool_ | np.uint8]],
|
|
17
17
|
/
|
|
18
18
|
) -> None:
|
|
19
19
|
if isinstance(value, bytes):
|
|
@@ -26,20 +26,19 @@ class Bit:
|
|
|
26
26
|
value = ''.join([bits[v] for v in value])
|
|
27
27
|
except (KeyError, TypeError):
|
|
28
28
|
raise ValueError('expected list[bool]')
|
|
29
|
+
elif not set(value).issubset({'0', '1'}):
|
|
30
|
+
raise ValueError('expected bit string')
|
|
29
31
|
|
|
30
32
|
length = len(value)
|
|
31
33
|
if length % 8 != 0:
|
|
32
34
|
value += '0' * (8 - (length % 8))
|
|
33
35
|
|
|
34
36
|
self._length = length
|
|
35
|
-
|
|
36
|
-
self._data = int(value, 2).to_bytes(len(value) // 8, byteorder='big')
|
|
37
|
-
except ValueError:
|
|
38
|
-
raise ValueError('expected bit string')
|
|
37
|
+
self._data = int(value, 2).to_bytes(len(value) // 8, byteorder='big')
|
|
39
38
|
elif is_ndarray(value):
|
|
40
39
|
import numpy as np
|
|
41
40
|
|
|
42
|
-
if value.dtype != np.
|
|
41
|
+
if value.dtype != np.bool_:
|
|
43
42
|
# skip error for result of np.unpackbits
|
|
44
43
|
if value.dtype != np.uint8 or np.any(value > 1):
|
|
45
44
|
raise ValueError('expected elements to be boolean')
|
|
@@ -65,7 +64,7 @@ class Bit:
|
|
|
65
64
|
# TODO improve
|
|
66
65
|
return [v != '0' for v in self.to_text()]
|
|
67
66
|
|
|
68
|
-
def to_numpy(self) -> np.ndarray[tuple[int, ...], np.dtype[np.
|
|
67
|
+
def to_numpy(self) -> np.ndarray[tuple[int, ...], np.dtype[np.bool_]]:
|
|
69
68
|
import numpy as np
|
|
70
69
|
|
|
71
70
|
return np.unpackbits(np.frombuffer(self._data, dtype=np.uint8), count=self._length).astype(bool)
|
|
@@ -105,6 +105,11 @@ class SparseVector:
|
|
|
105
105
|
def _from_sparse(self, arr: sparray | spmatrix, /) -> None:
|
|
106
106
|
value: coo_array | coo_matrix = arr.tocoo(copy=False) # type: ignore
|
|
107
107
|
|
|
108
|
+
# has_canonical_format added in scipy 1.12+
|
|
109
|
+
if not hasattr(value, 'has_canonical_format') or not value.has_canonical_format:
|
|
110
|
+
value = value.copy()
|
|
111
|
+
value.sum_duplicates()
|
|
112
|
+
|
|
108
113
|
shape = cast(tuple[int, ...], value.shape)
|
|
109
114
|
if len(shape) == 1:
|
|
110
115
|
self._dim = shape[0]
|
|
@@ -115,10 +120,18 @@ class SparseVector:
|
|
|
115
120
|
|
|
116
121
|
if hasattr(value, 'coords'):
|
|
117
122
|
# scipy 1.13+
|
|
118
|
-
|
|
123
|
+
indices = value.coords[-1].tolist()
|
|
119
124
|
else:
|
|
120
|
-
|
|
121
|
-
|
|
125
|
+
indices = value.col.tolist()
|
|
126
|
+
|
|
127
|
+
elements = [(i, v) for i, v in zip(indices, value.data) if v != 0]
|
|
128
|
+
|
|
129
|
+
# has_canonical_format added in scipy 1.12+
|
|
130
|
+
if not hasattr(value, 'has_canonical_format') or not value.has_canonical_format:
|
|
131
|
+
elements.sort()
|
|
132
|
+
|
|
133
|
+
self._indices = [v[0] for v in elements]
|
|
134
|
+
self._values = [float(v[1]) for v in elements]
|
|
122
135
|
|
|
123
136
|
def _from_dense(self, value: list[float] | ndarray, /) -> None:
|
|
124
137
|
self._dim = len(value)
|
|
@@ -54,12 +54,22 @@ class TestSparseVector:
|
|
|
54
54
|
if np is None or sparse is None:
|
|
55
55
|
pytest.skip('NumPy and SciPy required')
|
|
56
56
|
|
|
57
|
-
arr = sparse.coo_array(
|
|
57
|
+
arr = sparse.coo_array(([2, 3, 1, 0], ([2, 4, 0, 3],)), shape=(6,))
|
|
58
58
|
vec = SparseVector(arr)
|
|
59
59
|
assert vec.to_list() == [1, 0, 2, 0, 3, 0]
|
|
60
60
|
assert vec.indices() == [0, 2, 4]
|
|
61
61
|
assert isinstance(vec.values()[0], float)
|
|
62
62
|
|
|
63
|
+
def test_coo_array_duplicates(self) -> None:
|
|
64
|
+
if np is None or sparse is None:
|
|
65
|
+
pytest.skip('NumPy and SciPy required')
|
|
66
|
+
|
|
67
|
+
arr = sparse.coo_array(([1, 2], ([1, 1],)), shape=(3,))
|
|
68
|
+
assert arr.todense().tolist() == [0, 3, 0]
|
|
69
|
+
vec = SparseVector(arr)
|
|
70
|
+
assert vec.to_list() == [0, 3, 0]
|
|
71
|
+
assert vec.indices() == [1]
|
|
72
|
+
|
|
63
73
|
def test_coo_array_dimensions(self) -> None:
|
|
64
74
|
if np is None or sparse is None:
|
|
65
75
|
pytest.skip('NumPy and SciPy required')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|