You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas对比3亿行超大规模CSV文件并生成差异报告?

Hey there! As someone who’s dealt with massive CSV comparisons more times than I can count, I can tell you straight up: Pandas can handle 300 million-row CSV comparisons, but you can’t load the whole files at once—that’s a surefire way to crash your system (even 300M rows of basic data would take tens of gigabytes of RAM). Instead, we’ll use Pandas’ chunking feature to process the files in small batches, plus smart key management to efficiently track which records are new, deleted, or need field-by-field comparison. Let’s break down exactly how to do this:

Is Pandas Feasible for This Task?

Absolutely, but only with strategic chunking and memory optimization. Loading the full 300M rows directly is impossible for most machines, but Pandas’ read_csv supports a chunksize parameter that lets you process the file in manageable batches. We’ll pair this with set operations on keys to avoid redundant work.

Core Implementation Plan

Here’s the step-by-step strategy to make this efficient:

  1. Gather all unique keys first: Chunk through both files to collect every key. This lets us split keys into three groups:
    • Keys present in both files (need field-by-field comparison)
    • Keys only in the old file (marked D for deleted)
    • Keys only in the new file (marked N for new)
  2. Compare chunks of common keys: Load small batches of both files, merge them on the key column, and generate status codes for each field.
  3. Add deleted/new records: Create separate DataFrames for keys that only exist in one file, then combine all results into the final output.

Full Code Implementation

1. Collect All Keys from Both Files

First, we’ll chunk through each CSV to gather every unique key—this is lightweight and avoids loading full rows into memory.

import pandas as pd
import numpy as np

def collect_all_keys(file_path, chunksize=100_000):
    """Chunk through a CSV to collect all unique keys"""
    keys = set()
    for chunk in pd.read_csv(file_path, usecols=['key'], chunksize=chunksize):
        keys.update(chunk['key'].tolist())
    return keys

# Collect keys from both files
old_keys = collect_all_keys('file1.csv')
new_keys = collect_all_keys('file2.csv')

# Categorize keys
common_keys = old_keys & new_keys
deleted_keys = old_keys - new_keys
new_added_keys = new_keys - old_keys

2. Define Status Logic

Next, we’ll create a vectorized function to generate the status codes you specified (S, C, O, D, N):

def get_status(old_val, new_val):
    """Return status code based on old and new values"""
    if pd.isna(old_val) and pd.isna(new_val):
        return 'S'
    elif pd.isna(old_val):
        return 'N'
    elif pd.isna(new_val):
        return 'D'
    if old_val == new_val:
        return 'S'
    elif old_val != 0 and new_val == 0:
        return 'O'
    else:
        return 'C'

# Vectorize the function for faster batch processing
vectorized_get_status = np.vectorize(get_status)

3. Compare Chunks of Common Keys

We’ll load small batches of both files, filter for common keys, merge them, and generate statuses:

def compare_chunks(old_chunk, new_chunk):
    """Compare a chunk of old and new data, return statuses"""
    merged = pd.merge(old_chunk, new_chunk, on='key', suffixes=('_old', '_new'), how='inner')
    status_df = pd.DataFrame({'key': merged['key']})
    
    # Generate status for each field
    for col in old_chunk.columns.drop('key'):
        status_df[col] = vectorized_get_status(merged[f'{col}_old'], merged[f'{col}_new'])
    
    return status_df

chunksize = 100_000  # Adjust based on your machine's RAM (e.g., 200_000 for 16GB RAM)
result_chunks = []

# Process chunks from the old file
for old_chunk in pd.read_csv('file1.csv', chunksize=chunksize):
    # Filter to only common keys to reduce processing
    old_chunk = old_chunk[old_chunk['key'].isin(common_keys)]
    if old_chunk.empty:
        continue
    
    # Match with corresponding rows in the new file
    for new_chunk in pd.read_csv('file2.csv', chunksize=chunksize):
        new_chunk = new_chunk[new_chunk['key'].isin(old_chunk['key'])]
        if new_chunk.empty:
            continue
        
        # Compare and save results
        chunk_result = compare_chunks(old_chunk, new_chunk)
        result_chunks.append(chunk_result)
        
        # Remove processed keys to avoid duplicate work
        processed_keys = set(chunk_result['key'])
        old_chunk = old_chunk[~old_chunk['key'].isin(processed_keys)]
        if old_chunk.empty:
            break

# Combine results for common keys
common_result = pd.concat(result_chunks, ignore_index=True)

4. Add Deleted and New Records

Finally, we’ll create DataFrames for keys that only exist in one file:

# Create DataFrame for deleted records (D)
deleted_df = pd.DataFrame({'key': list(deleted_keys)})
for col in old_chunk.columns.drop('key'):
    deleted_df[col] = 'D'

# Create DataFrame for new records (N)
new_added_df = pd.DataFrame({'key': list(new_added_keys)})
for col in old_chunk.columns.drop('key'):
    new_added_df[col] = 'N'

# Combine all results and sort by key (optional)
final_result = pd.concat([common_result, deleted_df, new_added_df], ignore_index=True)
final_result = final_result.sort_values('key').reset_index(drop=True)

# Save the final comparison
final_result.to_csv('comparison_result.csv', index=False)

Key Optimization Tips

  • Adjust chunksize: Tweak this based on your available RAM—smaller chunks use less memory but take longer to process.
  • Optimize data types: Use the dtype parameter in read_csv to assign smaller data types (e.g., key as category, numeric fields as float32/int32 if precision allows) to reduce memory usage.
  • Use faster file formats: Convert your CSVs to Parquet or Feather first (using Pandas) — these formats are compressed and load much faster than CSV.
  • Multiprocessing: Use Python’s multiprocessing module to parallelize chunk comparisons across CPU cores for faster results.
  • Alternative: Dask: If Pandas chunking is still too slow, try Dask (fully Pandas-compatible, designed for distributed big data processing).

Test with Your Sample Data

Using your provided sample files, the final output will match exactly what you expected:

key,field1,field2,field3
001,S,C,O
002,S,S,S
003,D,D,D
004,N,N,N

内容的提问来源于stack exchange,提问作者karthik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:17:20