Catalyst Support Group logo
Catalyst
Support Group
Back to Insights
Operations Apr 26, 20266 min read

Building a reusable data cleaning pipeline instead of one-off scripts

What separating shared logic from dataset-specific logic actually buys you across a multi-dataset project.

The first time you clean a messy dataset, you write a script. The second time you clean a different but related dataset, most people write another script, because it feels faster than stopping to think about structure. By the fourth dataset, you're maintaining four scripts that all do roughly the same thing slightly differently, and fixing a bug in one doesn't fix it in the others.

I hit exactly this wall working across four related survey datasets for the same project, each with different structures and quality problems, but enough overlap that copy-pasting cleaning logic between them was clearly going to cause more bugs than it solved.

Splitting core logic from dataset-specific logic

The fix was separating what stayed the same from what didn't. A shared utilities file held the logic every dataset needed regardless of its shape: standardizing column names, handling missing values consistently, validating data types, flagging duplicate records. Each dataset then got its own thin file that called into those shared utilities and only handled what was actually unique to it.

One dataset, for example, had a genuinely strange problem: timestamp sequences that didn't make chronological sense because of inconsistent AM/PM entry. That correction logic didn't belong in the shared utilities, it was specific to that one dataset's quirks. But the missing-value handling and column standardization it also needed came straight from the shared core, no need to rewrite it.

Another dataset had a different problem entirely: enumerators didn't always enter names consistently, so records needed to be mapped back to a master reference list before they could be reliably grouped or filtered. Again, unique logic, but built on the same shared foundation as everything else.

Why this actually mattered

The obvious benefit is less duplicated code. The less obvious benefit showed up when I found a bug in how missing values were being handled, a fix that would have meant hunting down and patching four separate scripts if I'd built this the naive way. Instead it was one change in the shared file, and every dataset that depended on it was fixed at once.

There's a slower, less measurable benefit too. Once the architecture existed, cleaning a fifth dataset from the same survey cycle would take a fraction of the time the first one did, not because the new dataset would be simpler, but because most of the plumbing was already built and tested. That's the actual payoff of a reusable pipeline. It's not that the first dataset gets cleaned faster. It's that every dataset after it does.

The lesson, generalized

If you're cleaning your second or third related dataset and reaching for copy-paste, that's usually the signal to stop and separate the reusable logic from the dataset-specific logic instead. It costs more time upfront and pays that time back, with interest, on every dataset that follows.