DataFrame-first fuzzy matching with character n-grams and cosine similarity.
Project description
matchframe
DataFrame-first fuzzy matching for Python using character n-grams and cosine similarity, implemented from scratch (no RapidFuzz or external fuzzy libraries).
Why this package exists
Many teams need practical matching between messy text columns in spreadsheets and data pipelines. matchframe focuses on:
- simple API for analysts and data engineers
- transparent scoring math
- clean pandas DataFrame input/output
- easy-to-read, production-ready Python code
Features
- Accepts one DataFrame with two columns to compare
- Uses configurable character n-grams (
ngram_size) - Computes cosine similarity via sparse frequency vectors (
Counter) - Returns top matches with score %, rank, and decision label
- Friendly input validation and clear error messages
Installation
From source (current project)
pip install -e .
After publishing
pip install columnmatch
Quick usage
import pandas as pd
from matchframe import match_columns
df = pd.DataFrame(
{
"column1": ["apple ltd"],
"column2": ["apple limited", "appel ltd", "microsoft uk"],
}
)
result = match_columns(
df,
left_col="column1",
right_col="column2",
ngram_size=2,
top_k=3,
min_score=70,
match_threshold=90,
review_threshold=75,
)
print(result)
Main function
match_columns(...) signature:
match_columns(
df,
left_col="column1",
right_col="column2",
ngram_size=3,
top_k=3,
min_score=70,
match_threshold=90,
review_threshold=75,
preprocess=True,
remove_accents=True,
keep_original=True,
)
Parameters
df: input pandas DataFrameleft_col: source column to match fromright_col: candidate column to match againstngram_size: character n-gram size (commonly 2 or 3)top_k: number of top matches returned per left valuemin_score: minimum similarity percentage to keepmatch_threshold: score at/above this is classified asmatchreview_threshold: score at/above this and belowmatch_thresholdisreviewpreprocess: whether to clean text before matchingremove_accents: remove accents during preprocessingkeep_original: keep original values in output (True) or processed values (False)
Output columns
The result DataFrame includes:
left_valueright_valuematch_scorerankdecision
If preprocessing is enabled, it also includes:
left_processedright_processed
Sample input/output
Input values:
- left:
apple ltd - right candidates:
apple limited,appel ltd,microsoft uk
Typical output rows:
apple ltd | appel ltd | 91.4 | 1 | matchapple ltd | apple limited | 84.2 | 2 | review
(Exact numbers depend on ngram_size and preprocessing settings.)
How scoring works
- Preprocess text (lowercase, trim, punctuation removal, etc.)
- Convert each string to character n-grams
- Count n-gram frequencies using
collections.Counter - Compute cosine similarity:
[ \text{cosine_similarity}(x, y) = \frac{x \cdot y}{|x||y|} ]
- Convert to percentage:
[ \text{match_score} = 100 \times \text{cosine_similarity} ]
Development setup
python -m venv .venv
# Windows PowerShell
.\.venv\Scripts\Activate.ps1
pip install -e .[dev]
pytest
python examples/basic_example.py
python -m build
Roadmap
- blocking strategies for large datasets
- optional parallel scoring
- optional export helpers and richer diagnostics
- optional configurable preprocessing profiles
Contributing
- Fork the repo and create a feature branch.
- Add or update tests for your change.
- Run
pytestlocally. - Open a pull request with a clear description.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file columnmatch-0.1.0.tar.gz.
File metadata
- Download URL: columnmatch-0.1.0.tar.gz
- Upload date:
- Size: 8.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d3f0bd3cdf6caa9e824945c4716d2006dcbee36970b78e601621d8ce9328be6e
|
|
| MD5 |
f78cf4f484a7408f32561534ab0e513a
|
|
| BLAKE2b-256 |
f716a4ac6216711ad3143df93d13930507a3978c8c4aa3ebbeb6d721c6b14606
|
File details
Details for the file columnmatch-0.1.0-py3-none-any.whl.
File metadata
- Download URL: columnmatch-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd38fc98b7fe8025030bf641c1a7f80edaf8d245dd9ad7ae4d4332412a7741ae
|
|
| MD5 |
720f8ee6a14fedcc39bf0cadb5623531
|
|
| BLAKE2b-256 |
f6083d9fff8783f822e9e1664855b0edda20de98426371647df3006e85e40770
|