Skip to main content

Lightning-fast dataframe comparison library built in Rust with Python bindings

Project description

RDataCompy

Lightning-fast dataframe comparison library, implemented in Rust with Python bindings.

Overview

RDataCompy is a high-performance library for comparing dataframes, inspired by Capital One's datacompy. Built in Rust and leveraging Apache Arrow, it provides 40+ million cells/second throughput with comprehensive comparison reports.

Why RDataCompy?

  • 🚀 Blazing Fast: 40-46M cells/second (100-1000x faster than Python-based solutions)
  • Memory Efficient: Zero-copy operations using Apache Arrow columnar format
  • 🎯 Flexible: Configurable tolerance for numeric comparisons
  • Comprehensive: Detailed reports showing exact differences
  • 🔧 Multi-Format: Works with PyArrow, Pandas, PySpark, and Polars DataFrames
  • Decimal Support: Full DECIMAL(p,s) support with cross-precision compatibility

Installation

pip install rdatacompy

Optional Dependencies

# For PySpark support
pip install rdatacompy[spark]

# For Pandas support
pip install rdatacompy[pandas]

# For Polars support
pip install rdatacompy[polars]

# Install everything
pip install rdatacompy[all]

Quick Start

Basic Usage (PyArrow)

import pyarrow as pa
from rdatacompy import Compare

# Create sample tables
df1 = pa.table({
    'id': [1, 2, 3, 4],
    'value': [10.0, 20.0, 30.0, 40.0],
    'name': ['Alice', 'Bob', 'Charlie', 'David']
})

df2 = pa.table({
    'id': [1, 2, 3, 5],
    'value': [10.001, 20.0, 30.5, 50.0],
    'name': ['Alice', 'Bob', 'Chuck', 'Eve']
})

# Compare dataframes
comp = Compare(
    df1, 
    df2,
    join_columns=['id'],
    abs_tol=0.01,  # Absolute tolerance for floats
    df1_name='original',
    df2_name='updated'
)

# Print comprehensive report
print(comp.report())

Using with Pandas

import pandas as pd
from rdatacompy import Compare

df1 = pd.DataFrame({
    'id': [1, 2, 3],
    'amount': [100.50, 200.75, 300.25]
})

df2 = pd.DataFrame({
    'id': [1, 2, 3],
    'amount': [100.51, 200.75, 300.24]
})

# Directly compare Pandas DataFrames (auto-converted to Arrow)
comp = Compare(df1, df2, join_columns=['id'], abs_tol=0.01)
print(comp.report())

Using with PySpark

from pyspark.sql import SparkSession
from rdatacompy import Compare

spark = SparkSession.builder.getOrCreate()

df1 = spark.createDataFrame([(1, 100), (2, 200)], ['id', 'value'])
df2 = spark.createDataFrame([(1, 100), (2, 201)], ['id', 'value'])

# Directly compare Spark DataFrames (auto-converted to Arrow)
comp = Compare(df1, df2, join_columns=['id'])
print(comp.report())

Decimal Support

from decimal import Decimal
import pyarrow as pa
from rdatacompy import Compare

# Compare DECIMAL columns with different precision/scale
df1 = pa.table({
    'id': [1, 2, 3],
    'price': pa.array([
        Decimal('123.456789012345'),
        Decimal('999.999999999999'),
        Decimal('42.123456789012')
    ], type=pa.decimal128(28, 12))  # High precision
})

df2 = pa.table({
    'id': [1, 2, 3],
    'price': pa.array([
        Decimal('123.456789'),
        Decimal('999.999998'),
        Decimal('42.123457')
    ], type=pa.decimal128(18, 6))  # Lower precision
})

# Compare with tolerance - handles different precision automatically
comp = Compare(df1, df2, join_columns=['id'], abs_tol=0.00001)
print(comp.report())

Features

Comparison Report

The report includes:

  • DataFrame Summary: Row and column counts
  • Column Summary: Common columns, unique to each dataframe
  • Row Summary: Matched rows, unique rows, duplicates
  • Column Comparison: Which columns have differences
  • Sample Differences: Example rows with unequal values
  • Statistics: Number of differences, max difference, null differences

API Methods

comp = Compare(df1, df2, join_columns=['id'])

# Get full comparison report
report = comp.report()

# Check if dataframes match
matches = comp.matches()  # Returns bool

# Get common columns
common_cols = comp.intersect_columns()

# Get columns unique to each dataframe
df1_only = comp.df1_unq_columns()
df2_only = comp.df2_unq_columns()

Supported Data Types

  • ✅ Integers: int8, int16, int32, int64, uint8, uint16, uint32, uint64
  • ✅ Floats: float32, float64
  • ✅ Decimals: decimal128, decimal256 (with cross-precision compatibility)
  • ✅ Strings: utf8, large_utf8
  • ✅ Booleans
  • ✅ Dates: date32, date64
  • ✅ Timestamps (with timezone support)

Cross-Type Compatibility

RDataCompy is designed for real-world data migration scenarios:

# Compare different numeric types (int vs float vs decimal)
df1 = pa.table({'id': [1], 'val': pa.array([100], type=pa.int64())})
df2 = pa.table({'id': [1], 'val': pa.array([100.0], type=pa.float64())})
comp = Compare(df1, df2, join_columns=['id'])
comp.matches()  # True - types are compatible!

# Compare different decimal precisions
df1 = pa.table({'val': pa.array([Decimal('123.45')], type=pa.decimal128(28, 12))})
df2 = pa.table({'val': pa.array([Decimal('123.45')], type=pa.decimal128(18, 6))})
# Compares successfully - precision difference handled automatically

Performance

Benchmarked on a dataset with 150,000 rows × 200 columns (58.8M data points):

  • Comparison time: 1.3 seconds
  • Throughput: 46 million cells/second
  • Memory overhead: 16 MB (only stores differences)

vs datacompy

RDataCompy is significantly faster than Python-based solutions:

  • Columnar processing: Uses SIMD-optimized Arrow compute kernels
  • Zero-copy: Works directly on Arrow arrays without data duplication
  • Hash-based joins: O(n) row matching vs O(n²) pandas merge
  • No type inference: Arrow types known upfront (no runtime checks per column)

Development

Prerequisites

  • Rust 1.70+
  • Python 3.8+
  • maturin

Building from Source

# Clone repository
git clone https://github.com/yourusername/rdatacompy
cd rdatacompy

# Create virtual environment
python -m venv .venv
source .venv/bin/activate

# Install maturin
pip install maturin

# Build and install in development mode
maturin develop --release

# Run examples
python examples/basic_usage.py

Running Tests

# Rust tests
cargo test

# Python examples
python examples/test_multi_dataframe_types.py
python examples/test_decimal_types.py
python examples/benchmark_large.py

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

Apache-2.0

Acknowledgments

Roadmap

See TODO.md for planned features and improvements.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rdatacompy-0.1.1-cp312-cp312-win_amd64.whl (782.2 kB view details)

Uploaded CPython 3.12Windows x86-64

rdatacompy-0.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (910.9 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

rdatacompy-0.1.1-cp311-cp311-win_amd64.whl (781.0 kB view details)

Uploaded CPython 3.11Windows x86-64

rdatacompy-0.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (909.8 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

rdatacompy-0.1.1-cp310-cp310-win_amd64.whl (781.2 kB view details)

Uploaded CPython 3.10Windows x86-64

rdatacompy-0.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (910.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

rdatacompy-0.1.1-cp39-cp39-win_amd64.whl (781.4 kB view details)

Uploaded CPython 3.9Windows x86-64

rdatacompy-0.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (910.7 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

rdatacompy-0.1.1-cp38-cp38-win_amd64.whl (781.4 kB view details)

Uploaded CPython 3.8Windows x86-64

rdatacompy-0.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (910.8 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ x86-64

File details

Details for the file rdatacompy-0.1.1-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for rdatacompy-0.1.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 d315a824e7e8facd8b7f380e882f0e0c1996dc40063310e8b2ed5063862dfbd8
MD5 85af41815bde2ab8c31f0846df8c915f
BLAKE2b-256 af0caa105002d64656eed9fc712d4a9f8b955b116013a1582755e5ec0ee21c75

See more details on using hashes here.

File details

Details for the file rdatacompy-0.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rdatacompy-0.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e3829c0b89b2c31dd6ffd57d6d14edfb5e43a835014e50f44f7a821c5dd79a12
MD5 e03752576d30c773d877bd6f2333079c
BLAKE2b-256 63aa6c2f12e796eccfdb4ba229ac711742a085e90c51d7151f101459e7efdda7

See more details on using hashes here.

File details

Details for the file rdatacompy-0.1.1-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for rdatacompy-0.1.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 3117e7c205320f654115627ff0801ded00b875febf5c2fc193b3977ecff248b7
MD5 f905601c2944b3a24bb10e99348ac87a
BLAKE2b-256 c3bc1ff3fdab004251ffc6e18a3c0e4166d4c56165e8d345061036d25126a6ef

See more details on using hashes here.

File details

Details for the file rdatacompy-0.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rdatacompy-0.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e79ffe200aae881fbfa9de8d4375bba565b0eeb85fbebb66b8f906fc733ceecb
MD5 800ff2e0cf19e135cf8b97b345ed3753
BLAKE2b-256 956a199052bbf7db80f6bafefe7ff22f3466e7e1898af4c6cc0dcf71d0e861bb

See more details on using hashes here.

File details

Details for the file rdatacompy-0.1.1-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for rdatacompy-0.1.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 2dcf34ac16fc48c22564de0b1610d1689caaf645a720169c2ad25179b9dc85ca
MD5 5be4db2238a3f593e34f1043ca5bcb65
BLAKE2b-256 cacffb3bac9f30e5261ac411c22305a7cbda45b250e2a2e89341cf8374f79ad4

See more details on using hashes here.

File details

Details for the file rdatacompy-0.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rdatacompy-0.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 43c8b442f289787995ff089f96b2a75e2ab2c4fc4469b65cc2e6eda6afd6cb30
MD5 88cec31513c82826997ab20f1ec8140a
BLAKE2b-256 98f805e3c2fccf5b997bd8997c2962d88cc6f8483295ef099ecd22c35aa3cab6

See more details on using hashes here.

File details

Details for the file rdatacompy-0.1.1-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for rdatacompy-0.1.1-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 08178b7a21278571188bca4db4874c16c97b13f0cc51b33c36787c3cbe0d9ab0
MD5 4fd6e57b0e9aa4c779c7051252363a9c
BLAKE2b-256 521d9a3c30df63aebb2c33fde7d51cb7db28425e1e66b35e504e3f768fd6c9bc

See more details on using hashes here.

File details

Details for the file rdatacompy-0.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rdatacompy-0.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 51fb9fd8efbf7e8e76826fd4a1747f58d2650938627391e9692997c7d11a9a40
MD5 e77029ce12b3f0597136a7abf391b400
BLAKE2b-256 25f7c57f30b4f402f432ba5924a548540c644d030055fdd85f2a6cd89f767f23

See more details on using hashes here.

File details

Details for the file rdatacompy-0.1.1-cp38-cp38-win_amd64.whl.

File metadata

File hashes

Hashes for rdatacompy-0.1.1-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 10e889422c62b0b7595744b23487ae845d09eaca4749607edb820af0aec5bb09
MD5 450a2c7d85fa8595aea3439808cb1517
BLAKE2b-256 74cd4dcd04e9aa92da0423eac63b5c8fe7231b638636d51e300a2f23f80e5554

See more details on using hashes here.

File details

Details for the file rdatacompy-0.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rdatacompy-0.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4b69c80f8b9cecd294775ae8016c0b663cd9d53c012afcf833d1a36178cc3460
MD5 ca76984fd567cff8089fc581c029a6f7
BLAKE2b-256 486612dc85ccb3788bad8625f4c3f2ae8c2146bfd6a8a30054ddb19cd574a309

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page