Skip to content

API reference

This page documents every public-facing class, function, and enum exported by the valentine package. For task-oriented guides see Getting started, Matchers, Matcher results, and Evaluation metrics.

The top-level package exports:

from valentine import (
    valentine_match,      # main entry point
    ColumnPair,           # NamedTuple key for matches
    MatcherResults,       # immutable Mapping returned by valentine_match
    InvalidMatcherError,  # raised for invalid matcher arguments
)

valentine_match

Match columns across DataFrames.

Accepts any iterable of DataFrames (pandas or Polars) and matches columns across all unique pairs.

Parameters:

Name Type Description Default
dfs Iterable[DataFrame | DataFrame]

Two or more DataFrames to match against each other. Pandas and Polars frames may be mixed freely within the same call.

required
matcher BaseMatcher

The matching algorithm to use.

required
df_names list[str] | None

Optional names for each DataFrame. If not provided, defaults to "aaa", "bbb", etc.

None
instance_sample_size int | None

Optional max number of non-empty rows to use for instance-based sampling in matchers like Coma. If None, no sampling is applied.

1000

Returns:

Type Description
MatcherResults

Immutable mapping of ColumnPair to similarity scores, sorted high to low. Use .details to access per-matcher score breakdowns (when the matcher provides them).

Raises:

Type Description
ValueError

If fewer than 2 DataFrames are provided, or if df_names length does not match the number of DataFrames.

InvalidMatcherError

If matcher is not a valid BaseMatcher instance.

Examples:

Match two pandas DataFrames:

>>> matches = valentine_match([df1, df2], Coma())

Match Polars DataFrames:

>>> import polars as pl
>>> matches = valentine_match([pl_df1, pl_df2], Coma())

Match multiple DataFrames (computes all pairs):

>>> matches = valentine_match([df1, df2, df3], Coma(), df_names=["a", "b", "c"])

Inspect sub-matcher breakdowns (Coma only):

>>> for pair, score in matches.items():
...     details = matches.get_details(pair)
...     if details:
...         print(f"{pair.source_column} <-> {pair.target_column}: {details}")

ColumnPair

Bases: NamedTuple

A matched pair of columns from two tables.

Immutable, hashable key identifying a matched pair of columns. Used everywhere a match result or ground truth entry is required. Because it is a NamedTuple, it also supports positional indexing, iteration, and unpacking::

pair = ColumnPair("orders", "price", "sales", "amount")
pair.source_table  # "orders"
pair.source_column  # "price"
pair.target_table  # "sales"
pair.target_column  # "amount"
pair.source  # ("orders", "price")
pair.target  # ("sales", "amount")
st, sc, tt, tc = pair  # positional unpacking

Attributes:

Name Type Description
source_table str

Name of the source table.

source_column str

Name of the source column.

target_table str

Name of the target table.

target_column str

Name of the target column.

source_table instance-attribute

source_table: str

source_column instance-attribute

source_column: str

target_table instance-attribute

target_table: str

target_column instance-attribute

target_column: str

source property

source: tuple[str, str]

(source_table, source_column) pair.

target property

target: tuple[str, str]

(target_table, target_column) pair.


MatcherResults

Bases: Mapping

Immutable mapping of ColumnPair to similarity scores.

Returned by valentine_match and individual matcher methods. Results are sorted from highest to lowest similarity and cannot be mutated after creation (preventing accidental invalidation of cached derived views like one_to_one).

Aside from standard mapping operations (len, iteration, indexing), provides convenience methods for filtering, subsetting, and computing evaluation metrics.

Parameters:

Name Type Description Default
matches dict[ColumnPair, float]

Raw match scores.

required
details dict[ColumnPair, dict[str, float]] | None

Optional per-pair breakdown of sub-matcher scores (e.g. from Coma).

None

Mapping protocol

Operation Behaviour
len(results) Number of matches.
iter(results) Iterate ColumnPair keys in descending score order.
results[pair] Look up the similarity score for a given ColumnPair.
pair in results Check membership.
results.items() Yield (ColumnPair, float) pairs in descending score order.
results == other Equality with another MatcherResults or a plain dict[ColumnPair, float].

MatcherResults is not hashable (__hash__ is None).

Details

details

Per-pair sub-matcher score breakdowns.

When the matcher provides component scores (e.g. Coma's name, path, leaves, parents, instances matchers), this maps each ColumnPair to {matcher_name: score}.

Returns an empty dict when the matcher does not provide details.

get_details

Get the sub-matcher breakdown for a specific column pair.

Returns None if no details are available for the given pair.

Transformations

All transformations return a new MatcherResults instance; the original is left untouched. Sub-matcher details are carried over to the filtered subset.

one_to_one_hungarian

Globally optimal 1:1 column matching via Hungarian assignment.

This is the default 1:1 selector — it is what Precision / Recall / F1Score call when their one_to_one flag is set. Each source and target appears in at most one returned pair, with the assignment chosen to maximise total similarity over all valid one-to-one assignments. Cost is O(n³) on column counts via scipy.optimize.linear_sum_assignment — negligible for typical schema sizes — and almost always strictly better than the greedy variant.

Parameters:

Name Type Description Default
threshold float | None

Minimum similarity to keep. If None, uses the median similarity score.

None

Returns:

Type Description
MatcherResults

A new instance with the Hungarian-optimal one-to-one assignment, post-thresholding.

one_to_one_greedy

Greedy 1:1 column matching, kept for backwards compatibility.

Starting from the highest-scoring pair, greedily assigns each source and target column at most one match. Pairs below threshold are discarded. When threshold is None (the default), the median similarity score is used.

Greedy can lock in a locally-best pair that blocks a better globally-optimal assignment, so one_to_one_hungarian is the recommended default; this method is exposed for compatibility and for test pinning.

Parameters:

Name Type Description Default
threshold float | None

Minimum similarity to keep. If None, uses the median score.

None

Returns:

Type Description
MatcherResults

A new instance with the greedy 1:1 assignment.

one_to_one_mutual_top

Keep pairs where each side ranks the other in its top n.

Pair (s, t) survives iff t is among s's n highest- scoring targets AND s is among t's n highest-scoring sources. With n=1 this is the classic mutual nearest- neighbour filter — high-precision, drops one-sided affinities. Strictly stricter than one_to_one_hungarian: only mutually-confirmed pairs survive, even at the cost of recall.

Parameters:

Name Type Description Default
n int

Top-n cutoff per side (default 1 = mutual nearest neighbour).

1

Returns:

Type Description
MatcherResults

A new instance with only the mutually-confirmed pairs.

filter

Filter matches by minimum similarity score.

Parameters:

Name Type Description Default
min_score float

Minimum similarity score to keep.

required

Returns:

Type Description
MatcherResults

A new instance containing only matches with score >= min_score.

take_top_n

Keep the top n matches by score.

Parameters:

Name Type Description Default
n int

Number of matches to keep.

required

Returns:

Type Description
MatcherResults

A new instance with only the top n matches.

take_top_percent

Keep the top percent% of matches by score.

Parameters:

Name Type Description Default
percent int

Percentage of matches to keep (0-100).

required

Returns:

Type Description
MatcherResults

A new instance with only the top matches.

take_top_n_per_source

Keep the top n matches per source column.

Parameters:

Name Type Description Default
n int

Number of matches to keep per source column.

required

Returns:

Type Description
MatcherResults

A new instance with only the top n matches per source column.

get_copy

Return a shallow copy of this instance.

Metrics

get_metrics

Compute evaluation metrics against a ground truth.

Parameters:

Name Type Description Default
ground_truth list[tuple[str, str]] | list[ColumnPair]

Expected column matches. Can be simple column-name pairs like [("col_a", "col_b")] or full ColumnPair instances. When column-name pairs are used, table names are ignored during comparison.

required
metrics set[Metric]

Set of metric instances to compute (default: METRICS_CORE).

METRICS_CORE
one_to_one_method ('greedy', 'hungarian', 'mutual_top')

Selection algorithm passed to each metric's apply method for use when the metric's one_to_one flag is True (default: "hungarian").

"greedy"

Returns:

Type Description
dict[str, Any]

Metric name to score mapping.


InvalidMatcherError

Bases: Exception

Raised when a non-BaseMatcher object is passed as a matcher.

Deprecated alias

NotAValentineMatcher is kept as an alias for backward compatibility with pre-1.0 code and will be removed in a future release. New code should catch InvalidMatcherError directly.

Match (internal)

valentine.algorithms.match.Match is an internal dataclass used by matchers to build up result entries before they are merged into a dict[ColumnPair, float]. It is intentionally not re-exported from the top-level package and should not be used in user code — ColumnPair is the stable, public key type.


Matchers (valentine.algorithms)

Every matcher extends the abstract BaseMatcher class. The module exports:

from valentine.algorithms import (
    BaseMatcher,
    Coma,
    Cupid,
    DistributionBased,
    JaccardDistanceMatcher,
    SimilarityFlooding,
    # Enums used by the matchers:
    Formula, Policy, StringMatcher,
    # Groupings:
    schema_only_algorithms,
    instance_only_algorithms,
    schema_instance_algorithms,
    all_matchers,
    # Key types:
    ColumnPair,
)

The groupings are plain lists of class names:

Constant Contents
schema_only_algorithms ["SimilarityFlooding", "Cupid"]
instance_only_algorithms ["DistributionBased", "JaccardDistanceMatcher"]
schema_instance_algorithms ["Coma"]
all_matchers Union of the three lists above.

BaseMatcher

Abstract base. Subclasses must implement get_matches; get_matches_batch has a default fall-back that calls get_matches on each unique pair.

Bases: ABC

Abstract base class for every matching algorithm.

Subclasses must implement get_matches. get_matches_batch has a default fall-back that calls get_matches on each unique pair of tables; override it in subclasses that benefit from a holistic view of all tables (e.g. a global TF-IDF corpus or global distribution ranks).

get_matches

Match columns between two tables.

Parameters:

Name Type Description Default
source_input BaseTable

The source table.

required
target_input BaseTable

The target table.

required

Returns:

Type Description
dict

Mapping of ColumnPair to similarity score.

get_matches_batch

Match columns across all unique pairs of tables.

The default implementation calls get_matches for each pair independently. Algorithms that benefit from a holistic view of all tables (e.g. global TF-IDF corpus, global distribution ranks) can override this method.

Parameters:

Name Type Description Default
tables list[BaseTable]

Two or more tables to match.

required

Returns:

Type Description
dict

Combined matches across all pairs.

match_details

Per-pair score breakdowns from the most recent match call.

Returns a mapping from ColumnPair to a dictionary of {matcher_name: score} showing how each sub-matcher contributed to the final similarity. Empty by default; override in subclasses that combine multiple matchers (e.g. Coma).

Coma

Bases: BaseMatcher

Pure Python implementation of the COMA 3.0 schema matching algorithm.

COMA (COmbination of MAtching algorithms) works by composing multiple individual matchers — each targeting a different aspect of schema or data similarity — and combining their scores. This implementation faithfully reproduces the matching pipeline from the original Java COMA 3.0 Community Edition.

Schema matchers (enabled by use_schema=True, the default):

  • Name: trigram (Dice) similarity on column names.
  • Path: trigram similarity on dot-separated schema paths.
  • Leaves: name similarity across all leaf-level columns.
  • Parents: structural similarity via parent-level leaf comparison.

Instance matcher (enabled by use_instances=True):

  • TF-IDF cosine similarity: each cell value is treated as a document, a global IDF is computed across all columns of both tables, and per-column similarity is aggregated using a max-matching Dice formula.

The two groups can be used independently or together. At least one of use_schema or use_instances must be enabled.

After computing all-pairs similarity scores, a selection step filters results using bidirectional best-match logic (DIR_BOTH) controlled by max_n, delta, and threshold.

When matching more than two tables via get_matches_batch, the TF-IDF corpus is built once from all tables, giving each pair the benefit of global IDF statistics.

Populates MatcherResults.details with {name, path, leaves, parents, instances} sub-scores.

Parameters:

Name Type Description Default
max_n int

Maximum number of matches to keep per column. 0 means unlimited (default). Must be >= 0.

0
use_instances bool

Enable TF-IDF instance-based matching (default: False).

False
use_schema bool

Enable schema-based matching (default: True). At least one of use_schema or use_instances must be True.

True
delta float

Fraction from the best per-column score within which matches are kept. For example, 0.15 keeps all matches scoring within 15% of the best match for that column. Must be in [0, 1] (default: 0.15).

0.15
threshold float

Absolute minimum similarity score to keep a match. Must be in [0, 1] (default: 0.0).

0.0
instance_weight float

Weight for the instance matcher relative to schema matchers (which always have weight 1.0). Must be >= 0 (default: 1.0, uniform).

1.0

Cupid

Bases: BaseMatcher

Python implementation of the Cupid schema matching algorithm.

Cupid combines linguistic similarity of column names with structural similarity derived from schema tree shape, following the paper Generic Schema Matching with Cupid (Madhavan et al., VLDB 2001).

Parameters:

Name Type Description Default
leaf_w_struct float

Weight of structural similarity at leaf level, in [0, 1] (default: 0.2).

0.2
w_struct float

Weight of structural similarity at inner-node level, in [0, 1] (default: 0.2).

0.2
th_accept float

Acceptance similarity threshold for the final mapping, in [0, 1] (default: 0.7).

0.7
th_high float

High-confidence threshold used during structural propagation, in [0, 1] (default: 0.6).

0.6
th_low float

Low-confidence threshold used during structural propagation, in [0, 1] (default: 0.35).

0.35
c_inc float

Positive reinforcement coefficient for matching children (must be > 0, default: 1.2).

1.2
c_dec float

Negative reinforcement coefficient for non-matching children (must be > 0, default: 0.9).

0.9
th_ns float

Name-similarity threshold, in [0, 1] (default: 0.7).

0.7
process_num int

Number of worker processes (must be >= 1, default: 1).

1

DistributionBased

Bases: BaseMatcher

Distribution-based column matching.

Implementation of the algorithm from Automatic Discovery of Attributes in Relational Databases (Zhang et al., SIGMOD 2011). Columns are compared by quantile histograms of their value distributions; Earth Mover's Distance drives the ranking of matches within each cluster.

Parameters:

Name Type Description Default
threshold1 float

Distance threshold used in phase 1 (distribution clustering), in [0, 1] (default: 0.15).

0.15
threshold2 float

Distance threshold used in phase 2 (attribute clustering), in [0, 1] (default: 0.15).

0.15
quantiles int

Number of quantiles used for histogram summaries (must be >= 1, default: 256).

256
process_num int

Number of worker processes (must be >= 1, default: 1).

1
use_bloom_filters bool

When True, use Bloom filters for approximate set intersection in phase 2 (Section 4 of the paper). Trades a small false-positive rate for cheaper computation on large columns (default: False).

False

JaccardDistanceMatcher

Bases: BaseMatcher

Baseline instance-based matcher using Jaccard similarity.

Columns are compared by Jaccard similarity of their value sets, with element equality decided by a configurable string distance function. This is a simple but effective baseline for instance-based matching.

Parameters:

Name Type Description Default
threshold_dist float

Acceptance threshold above which two string values are considered equal under the chosen distance_fun, in [0, 1] (default: 0.8). Ignored when distance_fun is StringDistanceFunction.Exact. For StringDistanceFunction.Embedding, the threshold is applied to cosine similarity of sentence-transformer embeddings; ~0.7 is a typical operating point.

0.8
distance_fun StringDistanceFunction

String similarity function. One of StringDistanceFunction.Levenshtein (default), StringDistanceFunction.DamerauLevenshtein, StringDistanceFunction.Hamming, StringDistanceFunction.Jaro, StringDistanceFunction.JaroWinkler, StringDistanceFunction.Exact, or StringDistanceFunction.Embedding.

Levenshtein
process_num int

Number of worker threads passed to rapidfuzz.process.cdist (must be >= 1, default: 1). Earlier versions used a multiprocessing.Pool; with rapidfuzz the inner kernel is already C++ and parallelises via OpenMP threads, so the pool is no longer needed.

1
embedding_model str

Name of the sentence-transformers model used when distance_fun=StringDistanceFunction.Embedding (default: "all-MiniLM-L6-v2", a 23 MB / 384-dim model that runs well on CPU). Ignored for non-embedding distances.

'all-MiniLM-L6-v2'
embedding_device str or None

Device to load the embedding model on. Passed straight through to SentenceTransformer. None (the default) lets the library auto-detect — usually "cuda" if a GPU is present, "mps" on Apple Silicon, otherwise "cpu". Pass "cpu", "cuda", "cuda:1", or "mps" to force a specific device. Ignored for non-embedding distances.

None
embedding_batch_size int or None

Batch size used for the global model.encode call. None (the default) does not pass the kwarg, letting sentence-transformers use its own default (32). Pass an explicit value (e.g. 128 or 256) to amortise per-call overhead when encoding large vocabularies on capable hardware. Ignored for non-embedding distances.

None
tversky_alpha float

Tversky penalty for unmatched values on the reference side (default: 1.0). The pair-similarity reduction is T(A, B; a, b) = |A∩B| / (|A∩B| + a·|A-B| + b·|B-A|), symmetrised by computing both T(A, B) and T(B, A) and taking the max so the matcher remains direction-agnostic. With a = b = 1.0 this reduces to Jaccard; with a = 1.0, β = 0.0 (or vice versa) it reduces to max(|∩|/|A|, |∩|/|B|), i.e. set containment — the right choice when one column is expected to be a subset of the other. Intermediate values trade off between these extremes.

1.0
tversky_beta float

Tversky penalty for unmatched values on the other side (default: 1.0). See tversky_alpha.

1.0

StringDistanceFunction

Bases: Enum

Element-equality functions supported by JaccardDistanceMatcher.

Levenshtein class-attribute instance-attribute

Levenshtein = auto()

Normalized Levenshtein ratio (default).

DamerauLevenshtein class-attribute instance-attribute

DamerauLevenshtein = auto()

Normalized Damerau-Levenshtein ratio.

Jaro class-attribute instance-attribute

Jaro = auto()

Jaro similarity.

JaroWinkler class-attribute instance-attribute

JaroWinkler = auto()

Jaro-Winkler similarity.

Hamming class-attribute instance-attribute

Hamming = auto()

Normalized Hamming distance (strings of equal length).

Exact class-attribute instance-attribute

Exact = auto()

Exact string equality (forces the threshold to 1.0).

Embedding class-attribute instance-attribute

Embedding = auto()

Cosine similarity of sentence-transformer embeddings. Requires the sentence-transformers extra (pip install valentine[embeddings]).

from valentine.algorithms.jaccard_distance import StringDistanceFunction
from valentine.algorithms import JaccardDistanceMatcher

m = JaccardDistanceMatcher(
    threshold_dist=0.9,
    distance_fun=StringDistanceFunction.JaroWinkler,
)

SimilarityFlooding

Bases: BaseMatcher

Python implementation of the Similarity Flooding schema matcher.

Similarity Flooding (Melnik, Garcia-Molina, Rahm — ICDE 2002) treats each schema as a labelled graph and iteratively propagates an initial element-level similarity across the graph structure until a fixpoint is reached.

Parameters:

Name Type Description Default
coeff_policy Policy

Coefficient policy for the propagation graph. One of Policy.INVERSE_AVERAGE (default) or Policy.INVERSE_PRODUCT.

INVERSE_AVERAGE
formula Formula

Fixpoint iteration formula. One of Formula.BASIC, Formula.FORMULA_A, Formula.FORMULA_B, or Formula.FORMULA_C (default).

FORMULA_C
string_matcher StringMatcher

String similarity function used for the initial element-level mapping. One of StringMatcher.PREFIX_SUFFIX (default), StringMatcher.PREFIX_SUFFIX_TFIDF, or StringMatcher.LEVENSHTEIN.

PREFIX_SUFFIX
tfidf_corpus list[BaseTable] | None

Additional tables to include when computing IDF weights for the PREFIX_SUFFIX_TFIDF matcher. Ignored for other string matchers.

None

Policy

Bases: Enum

Coefficient policy for the propagation graph.

INVERSE_AVERAGE class-attribute instance-attribute

INVERSE_AVERAGE = auto()

Inverse of the average in-degree (default).

INVERSE_PRODUCT class-attribute instance-attribute

INVERSE_PRODUCT = auto()

Inverse of the product of in-degrees.

Formula

Bases: Enum

Fixpoint iteration formula.

BASIC class-attribute instance-attribute

BASIC = auto()

Basic fixpoint formula.

FORMULA_A class-attribute instance-attribute

FORMULA_A = auto()

Variant A from the Similarity Flooding paper.

FORMULA_B class-attribute instance-attribute

FORMULA_B = auto()

Variant B from the Similarity Flooding paper.

FORMULA_C class-attribute instance-attribute

FORMULA_C = auto()

Variant C (default in Valentine).

StringMatcher

Bases: Enum

String matching function for the initial similarity mapping.

PREFIX_SUFFIX class-attribute instance-attribute

PREFIX_SUFFIX = auto()

Prefix/suffix trigram matcher (default).

PREFIX_SUFFIX_TFIDF class-attribute instance-attribute

PREFIX_SUFFIX_TFIDF = auto()

Prefix/suffix matcher weighted by IDF computed from the corpus.

LEVENSHTEIN class-attribute instance-attribute

LEVENSHTEIN = auto()

Normalized Levenshtein similarity on node labels.


Metrics (valentine.metrics)

from valentine.metrics import (
    Metric,                       # abstract base class
    Precision,
    Recall,
    F1Score,
    PrecisionTopNPercent,
    RecallAtSizeofGroundTruth,
    MeanReciprocalRank,
    METRICS_CORE,
    METRICS_ALL,
    METRICS_PRECISION_RECALL,
    METRICS_PRECISION_INCREASING_N,
)

Metric

Abstract base class (@dataclass(frozen=True)). Subclass to implement custom metrics:

@dataclass(eq=True, frozen=True)
class MyMetric(Metric):
    threshold: float = 0.5

    def apply(self, matches, ground_truth):
        # ... compute score ...
        return self.return_format(score)

apply

Apply the metric to a MatcherResults instance, given ground truth.

Parameters:

Name Type Description Default
matches MatcherResults

The MatcherResults instance, obtained from valentine_match.

required
ground_truth list

Expected column matches. Either column-name pairs [("src_col", "tgt_col"), ...] (table names ignored during comparison) or full ColumnPair instances for table-aware comparison.

required
one_to_one_method ('greedy', 'hungarian', 'mutual_top')

Selection algorithm used when the metric's one_to_one field is True. Defaults to "hungarian" (globally optimal). "greedy" matches the legacy behaviour; "mutual_top" keeps only mutually-confirmed pairs (top-1 on each side). Ignored when one_to_one is False or for metrics that do not apply 1:1 filtering.

"greedy"

name

The name of the metric, as it appears in the metric results.

Returns:

Type Description
str

The name of the metric.

return_format

The return format of the apply method.

Parameters:

Name Type Description Default
value Any

The metric value or score.

required

Returns:

Type Description
Dict[str, Any]

The formatted metric value or score.

Built-in metrics

All built-in metrics are @dataclass(frozen=True) and hashable, so they can live in the predefined metric sets.

Precision

Bases: Metric

Precision = TP / (TP + FP).

Attributes:

Name Type Description
one_to_one bool

Whether to apply the one-to-one filter to the MatcherResults first.

Recall

Bases: Metric

Recall = TP / (TP + FN).

Attributes:

Name Type Description
one_to_one bool

Whether to apply the one-to-one filter to the MatcherResults first.

F1Score

Bases: Metric

F1 score = 2 * (Precision * Recall) / (Precision + Recall).

Attributes:

Name Type Description
one_to_one bool

Whether to apply the one-to-one filter to the MatcherResults first.

PrecisionTopNPercent

Bases: Metric

Precision restricted to the top-N% of predicted matches by score.

Attributes:

Name Type Description
one_to_one bool

Whether to apply the one-to-one filter to the MatcherResults first.

n int

Percentage of matches to consider (0-100).

RecallAtSizeofGroundTruth

Bases: Metric

Recall when considering the top-|GT| predictions.

This simulates selecting as many predictions as there are gold pairs and computing recall at that cutoff: TP / (TP + FN) where the candidate set is the top-len(ground_truth) matches by score.

Attributes:

Name Type Description
one_to_one bool

Whether to apply the one-to-one filter to the MatcherResults first.

MeanReciprocalRank

Bases: Metric

Mean Reciprocal Rank (MRR).

For each ground truth pair, finds its rank (1-indexed position) in the matcher results sorted by descending score. The reciprocal rank is 1/rank if the pair is found, or 0 if absent. MRR is the mean of reciprocal ranks across all ground truth pairs.

Attributes:

Name Type Description
one_to_one bool

Whether to apply the one-to-one filter to the MatcherResults first.

Predefined metric sets

Set Contents
METRICS_CORE Precision, Recall, F1Score, PrecisionTopNPercent, RecallAtSizeofGroundTruth, MeanReciprocalRank (defaults).
METRICS_ALL Both one_to_one=True and one_to_one=False variants of Precision, Recall, F1Score, plus PrecisionTopNPercent, RecallAtSizeofGroundTruth, and MeanReciprocalRank.
METRICS_PRECISION_RECALL {Precision(), Recall()}.
METRICS_PRECISION_INCREASING_N PrecisionTopNPercent for n ∈ {10, 20, 30, …, 100}.

Data sources (valentine.data_sources)

Valentine wraps each DataFrame in a DataframeTable (pandas) or PolarsTable (Polars) before handing it to a matcher. Most users never touch this layer — valentine_match auto-detects the frame type and builds the tables for you — but the classes are public so that custom matchers and custom data sources can be written against the abstractions.

from valentine.data_sources import (
    BaseTable,
    BaseColumn,
    DataframeTable,
    DataframeColumn,
)

# With the polars extra installed:
from valentine.data_sources import PolarsTable, PolarsColumn

BaseTable

Bases: ABC

Abstract class representing a table.

Subclasses wrap a concrete frame type (pandas DataFrame, Polars DataFrame, etc.) and expose its contents through a uniform column-oriented interface that the matching algorithms consume.

Abstract members (must be provided by subclasses):

Table name. Becomes source_table/target_table in emitted ColumnPair instances.

Stable identifier used internally to key per-table state.

All columns in the table.

Return the underlying frame object (pandas/Polars/…).

Whether the table has zero rows.

Concrete members (provided by BaseTable, override if needed):

Return the frame used for instance-based sampling. Defaults to get_df.

Return columns built from the instance-sampled frame. Defaults to get_columns.

Return a {column_name: column.unique_identifier} lookup.

Map a dtype string to a canonical Valentine type.

Recognises text-like types from both pandas (object, string, str) and Polars (Utf8, String, Categorical), as well as numeric and date categories.

BaseColumn

Bases: ABC

Abstract class representing a single column.

A BaseColumn knows its name, its values, and its detected data type. Implement this alongside BaseTable to plug a non-DataFrame backend into Valentine's matchers.

Abstract members:

Column name.

Stable identifier used internally to key per-column state.

Detected type: one of "varchar", "int", "float", or "date".

The column's values.

Concrete members:

Number of elements in data.

True when size is 0.

DataframeTable

Bases: BaseTable

A BaseTable backed by a pandas DataFrame.

The concrete implementation used by valentine_match. Automatic data-type detection classifies each column as "varchar", "int", "float", or "date" based on the DataFrame's dtype and content.

Parameters:

Name Type Description Default
df DataFrame

The DataFrame to wrap.

required
name str

Name of the table. Used as source_table / target_table in emitted ColumnPair instances.

required
instance_sample_size int | None

Cap on the number of non-empty rows sampled per column. None uses the full DataFrame; 0 exposes no instance data at all. Must be >= 0 or None (default: 1000).

1000

DataframeColumn

Bases: BaseColumn

A BaseColumn adapter for a single pandas Series.

Constructed internally by DataframeTable; exposes the column name, detected data type, unique identifier, and sampled instance values via the standard BaseColumn interface.

PolarsTable

Bases: BaseTable

A BaseTable backed by a Polars DataFrame.

Drop-in replacement for DataframeTable; all matching algorithms work identically because they consume the BaseTable / BaseColumn interface, not the underlying frame type.

Parameters:

Name Type Description Default
df DataFrame

The Polars DataFrame to wrap.

required
name str

A human-readable table name.

required
instance_sample_size int | None

Maximum number of non-empty rows kept for instance-based matchers. None keeps all rows, 0 keeps none.

1000

PolarsColumn

Bases: BaseColumn

A BaseColumn adapter for a single Polars Series.

Constructed internally by PolarsTable; exposes the column name, detected data type, unique identifier, and sampled instance values via the standard BaseColumn interface.

Writing a custom data source

If your data doesn't live in a pandas DataFrame, implement BaseTable and BaseColumn directly. A minimal custom source just needs a name, a unique identifier, and the ability to enumerate its columns:

import uuid
import pandas as pd

from valentine import valentine_match
from valentine.algorithms import Coma
from valentine.data_sources import BaseColumn, BaseTable


class DictColumn(BaseColumn):
    def __init__(self, name: str, data: list, data_type: str = "varchar"):
        self._name = name
        self._data = data
        self._data_type = data_type
        self._guid = str(uuid.uuid4())

    @property
    def name(self) -> str:
        return self._name

    @property
    def unique_identifier(self) -> str:
        return self._guid

    @property
    def data_type(self) -> str:
        return self._data_type

    @property
    def data(self) -> list:
        return self._data


class DictTable(BaseTable):
    def __init__(self, name: str, columns: dict[str, list]):
        self._name = name
        self._guid = str(uuid.uuid4())
        self._columns = [DictColumn(k, v) for k, v in columns.items()]

    @property
    def name(self) -> str:
        return self._name

    @property
    def unique_identifier(self) -> str:
        return self._guid

    def get_columns(self) -> list[BaseColumn]:
        return self._columns

    def get_df(self) -> pd.DataFrame:
        return pd.DataFrame({c.name: c.data for c in self._columns})

    @property
    def is_empty(self) -> bool:
        return all(len(c.data) == 0 for c in self._columns)


# Matchers call get_matches / get_matches_batch directly on BaseTable
# instances, so custom sources bypass valentine_match:
source = DictTable("hr", {"emp_id": [1, 2, 3], "fname": ["a", "b", "c"]})
target = DictTable("payroll", {"employee_number": [1, 2, 3], "first_name": ["a", "b", "c"]})

raw = Coma().get_matches_batch([source, target])

If you want to reuse Valentine's instance-sampling logic, override get_instances_df to return a capped DataFrame. Custom sources are accepted by every built-in matcher — only valentine_match itself is DataFrame-specific.