关于 dataset-comparer
dataset-comparer 是用于比较 CSV 和 Excel 数据集的 Python 工具,适合数据校验与变更追踪。它支持按键列或行位置匹配,并可将差异导出为多种报告。
主要功能
- 01检测新增、删除和变更行
- 02按键列或行位置匹配
- 03比较列结构
- 04忽略或指定比较列
- 05生成 HTML、CSV 和 JSON 报告
适用场景
- 01校验数据迁移结果
- 02核对 ETL 输出
- 03查找上次同步后的新增记录
- 04检测导出文件的结构变化
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dkyazzentwatwa/ chatgpt-skills --skill dataset-comparer安装后在 Claude Code 中输入/dataset-comparer确认已加载。
附带文件scripts/dataset_comparer.pyscripts/requirements.txt
详细介绍
数据集比较器
比较两个 CSV/Excel 数据集,找出差异、新增项、删除项和值变更。
功能
- 行比较:查找新增、删除和匹配的行
- 值变更:检测匹配行中的值变更
- 列比较:识别架构差异
- 统计信息:汇总差异
- 差异报告:支持 HTML、CSV 和 JSON 输出
- 灵活匹配:按键列或行位置进行比较
快速入门
from dataset_comparer import DatasetComparer
comparer = DatasetComparer()
comparer.load("old_data.csv", "new_data.csv")
# Compare by key column
diff = comparer.compare(key_columns=["id"])
print(f"Added rows: {diff['added_count']}")
print(f"Removed rows: {diff['removed_count']}")
print(f"Changed rows: {diff['changed_count']}")
# Generate report
comparer.generate_report("diff_report.html")
CLI 用法
# Basic comparison
python dataset_comparer.py --old old.csv --new new.csv
# Compare by key column
python dataset_comparer.py --old old.csv --new new.csv --key id
# Multiple key columns
python dataset_comparer.py --old old.csv --new new.csv --key id,date
# Generate HTML report
python dataset_comparer.py --old old.csv --new new.csv --key id --report diff.html
# Export differences to CSV
python dataset_comparer.py --old old.csv --new new.csv --key id --output diff.csv
# JSON output
python dataset_comparer.py --old old.csv --new new.csv --key id --json
# Ignore specific columns
python dataset_comparer.py --old old.csv --new new.csv --key id --ignore updated_at,modified_date
# Compare only specific columns
python dataset_comparer.py --old old.csv --new new.csv --key id --columns name,email,status
API 参考
DatasetComparer 类
class DatasetComparer:
def __init__(self)
# Data loading
def load(self, old_path: str, new_path: str) -> 'DatasetComparer'
def load_dataframes(self, old_df: pd.DataFrame,
new_df: pd.DataFrame) -> 'DatasetComparer'
# Comparison
def compare(self, key_columns: list = None,
ignore_columns: list = None,
compare_columns: list = None) -> dict
# Detailed results
def get_added_rows(self) -> pd.DataFrame
def get_removed_rows(self) -> pd.DataFrame
def get_changed_rows(self) -> pd.DataFrame
def get_unchanged_rows(self) -> pd.DataFrame
# Schema comparison
def compare_schema(self) -> dict
# Reports
def generate_report(self, output: str, format: str = "html") -> str
def to_dataframe(self) -> pd.DataFrame
def summary(self) -> str
比较方法
基于键的比较
通过匹配键列(如主键)来比较行:
diff = comparer.compare(key_columns=["customer_id"])
# Multiple keys for composite matching
diff = comparer.compare(key_columns=["order_id", "product_id"])
基于位置的比较
根据行的位置(行号)进行比较:
diff = comparer.compare() # No keys = positional comparison
输出格式
比较结果
{
"summary": {
"old_rows": 1000,
"new_rows": 1050,
"added_count": 75,
"removed_count": 25,
"changed_count": 50,
"unchanged_count": 900,
"total_differences": 150
},
"schema_changes": {
"added_columns": ["new_field"],
"removed_columns": ["old_field"],
"type_changes": [
{"column": "amount", "old_type": "int64", "new_type": "float64"}
]
},
"key_columns": ["id"],
"compared_columns": ["name", "email", "status"],
"ignored_columns": ["updated_at"]
}
变更行详情
changes = comparer.get_changed_rows()
# Returns DataFrame with columns:
# _key: Key value(s) for the row
# _column: Column that changed
# _old_value: Original value
# _new_value: New value
架构比较
比较列结构:
schema = comparer.compare_schema()
# Returns:
{
"old_columns": ["id", "name", "old_field"],
"new_columns": ["id", "name", "new_field"],
"common_columns": ["id", "name"],
"added_columns": ["new_field"],
"removed_columns": ["old_field"],
"type_changes": [
{"column": "price", "old_type": "int64", "new_type": "float64"}
],
"old_row_count": 1000,
"new_row_count": 1050
}
筛选选项
忽略列
比较时跳过特定列:
diff = comparer.compare(
key_columns=["id"],
ignore_columns=["updated_at", "modified_by", "timestamp"]
)
比较指定列
仅比较所选列:
diff = comparer.compare(
key_columns=["id"],
compare_columns=["name", "email", "status"] # Only these columns
)
报告格式
HTML 报告
comparer.generate_report("diff_report.html", format="html")
功能:
- 汇总统计信息
- 交互式表格
- 变更按颜色标记(绿色 = 新增,红色 = 删除,黄色 = 变更)
- 架构比较部分
CSV 导出
comparer.generate_report("diff_report.csv", format="csv")
以表格形式包含所有差异。
JSON 输出
comparer.generate_report("diff_report.json", format="json")
以 JSON 格式提供完整的差异数据。
示例工作流
数据迁移验证
comparer = DatasetComparer()
comparer.load("source_data.csv", "migrated_data.csv")
diff = comparer.compare(key_columns=["id"])
if diff["summary"]["total_differences"] == 0:
print("Migration successful - no differences!")
else:
print(f"Found {diff['summary']['total_differences']} differences")
comparer.generate_report("migration_issues.html")
ETL 管道验证
comparer = DatasetComparer()
comparer.load("yesterday.csv", "today.csv")
diff = comparer.compare(
key_columns=["transaction_id"],
ignore_columns=["processing_timestamp"]
)
# Check for unexpected changes
changed = comparer.get_changed_rows()
if len(changed) > 0:
print("Warning: Historical records changed!")
print(changed)
增量更新检测
comparer = DatasetComparer()
comparer.load("last_sync.csv", "current.csv")
diff = comparer.compare(key_columns=["customer_id"])
# Get new records for processing
new_records = comparer.get_added_rows()
print(f"New records to process: {len(new_records)}")
# Get deleted records
deleted = comparer.get_removed_rows()
print(f"Records to deactivate: {len(deleted)}")
架构变更检测
comparer = DatasetComparer()
comparer.load("v1_export.csv", "v2_export.csv")
schema = comparer.compare_schema()
if schema["added_columns"]:
print(f"New columns: {schema['added_columns']}")
if schema["removed_columns"]:
print(f"Removed columns: {schema['removed_columns']}")
if schema["type_changes"]:
for change in schema["type_changes"]:
print(f"Type change: {change['column']} "
f"({change['old_type']} -> {change['new_type']})")
大型数据集使用提示
对于非常大的数据集:
# Compare in chunks
comparer = DatasetComparer()
comparer.load("large_old.csv", "large_new.csv")
# Use key column for efficient matching
diff = comparer.compare(key_columns=["id"])
# Export only differences (not full data)
comparer.generate_report("diff_only.csv", format="csv")
依赖项
- pandas>=2.0.0
- numpy>=1.24.0
评论
支持 Markdown