Skip to main content

embedding-dedupe

PyPI Python License: MIT

Deduplicate near-identical embedding records by cosine similarity. Pure Python, zero runtime dependencies.

Python port of @mukundakatta/embedding-dedupe. Same algorithm, ergonomic Python API.

Install

pip install embedding-dedupe
# Optional: faster cosine via numpy
pip install "embedding-dedupe[numpy]"

Usage

from embedding_dedupe import dedupe

records = [
    {"id": "a", "embedding": [0.10, 0.20, 0.30], "text": "Cats are great."},
    {"id": "b", "embedding": [0.10, 0.20, 0.31], "text": "Cats are great pets."},   # near-dup of a
    {"id": "c", "embedding": [0.90, 0.10, 0.05], "text": "Stock prices fell."},
]

# Default: keep the lowest-id record from each cluster (deterministic).
dedupe(records, threshold=0.95)
# -> [
#      {"id": "a", "embedding": [0.10, 0.20, 0.30], "text": "Cats are great."},
#      {"id": "c", "embedding": [0.90, 0.10, 0.05], "text": "Stock prices fell."},
#    ]

# Or: keep the record with the longest text (ties -> lowest id).
dedupe(records, threshold=0.95, keep="longest")
# -> [
#      {"id": "b", "embedding": [0.10, 0.20, 0.31], "text": "Cats are great pets."},
#      {"id": "c", "embedding": [0.90, 0.10, 0.05], "text": "Stock prices fell."},
#    ]

API

dedupe(
    records,                  # list[dict]
    threshold=0.95,           # cosine sim above which two records are duplicates
    key="id",                 # record id field name
    vector="embedding",       # embedding field name
    keep="first",             # "first" (lowest-id) or "longest" (longest .text)
) -> list[dict]

cosine(a, b) is also exported for ad-hoc use.

Algorithm

Greedy single-link clustering: scan records in input order, place each into the first existing cluster whose anchor vector is within threshold, else start a new cluster. From each cluster, return one survivor according to keep. Cluster output order matches input order (= order in which clusters were created).

O(n * k) where k is the cluster count -- fine up to ~100k records. For larger sets, plug in an ANN index upstream and dedupe within candidates.

API differences from the JS sibling

  • JS: dedupeEmbeddings(items, { threshold }) returning { kept, duplicates }. Python: dedupe(records, threshold=0.95, key=, vector=, keep=) returning a flat list[dict] of survivors.
  • The default threshold is 0.95 (was 0.98 in JS) -- tuned for typical OpenAI/Anthropic embedding noise.
  • New keep="longest" strategy mirrors a common request -- prefer the most informative chunk in each cluster.

See the JS sibling for the original heuristics and design notes.

Metadata

Release files for embedding-dedupe 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for embedding-dedupe 0.1.0
File Size Uploaded Provenance Actions
embedding_dedupe-0.1.0.tar.gz 5.7 kB Without provenance Details for embedding_dedupe-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for embedding-dedupe 0.1.0
File Interpreter ABI Platform Actions
embedding_dedupe-0.1.0-py3-none-any.whl Python 3 none any Details for embedding_dedupe-0.1.0-py3-none-any.whl

Total release size: 11.3 kB

Release files / embedding_dedupe-0.1.0.tar.gz

Download URL embedding_dedupe-0.1.0.tar.gz
Size 5.7 kB
Tags Source
SHA-256 checksum
How to use checksums
d8525a9d2bd3a48386f5993ed2c5d034ea731432b53234a77531906d0ab4a249
BLAKE2b-256 checksum
How to use checksums
2e28adf7b7c4ebc1416aadc2ad1ed14511cb1f7edb90d9bdd53d8ab1ee6eafff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / embedding_dedupe-0.1.0-py3-none-any.whl

Download URL embedding_dedupe-0.1.0-py3-none-any.whl
Size 5.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
24cab99651b23ae5df617292cea0efc806cfd46472513a9bd759d2df0ffb14f1
BLAKE2b-256 checksum
How to use checksums
0039c1b84676ee70f9498aea7d56d0a328990680c3fc0228b0f7ec561906af3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Security for embedding-dedupe 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page