DataFrame-first fuzzy matching for Python using character n-grams and cosine similarity, implemented from scratch (no RapidFuzz or external fuzzy libraries).
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
- 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
pip install -e .pip install columnmatchimport 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)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,
)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)
The result DataFrame includes:
left_valueright_valuematch_scorerankdecision
If preprocessing is enabled, it also includes:
left_processedright_processed
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.)
- 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} ]
python -m venv .venv
# Windows PowerShell
.\.venv\Scripts\Activate.ps1
pip install -e .[dev]
pytest
python examples/basic_example.py
python -m build- blocking strategies for large datasets
- optional parallel scoring
- optional export helpers and richer diagnostics
- optional configurable preprocessing profiles
- 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.
MIT