Guide

How to clean battery cycler data (Arbin, Neware, Maccor, BioLogic)

Every cycler exports a slightly different CSV, and every one ships noise: current spikes at step transitions, frozen thermocouples, and samples dropped when the logger hiccups. Here is how to clean battery cycler data before you compute capacity fade or dQ/dV — without erasing the degradation you are measuring.

Why cycler data is messy

Format gotchas per cycler

CyclerWatch out for
Arbinseparate Global/Step time columns; current sign convention; large multi-sheet exports
Newareunits differ by export template (mA vs A); step/cycle indices you must keep
Maccorfixed-width / tab quirks; time may reset per step
BioLogicnative .mpr must be converted to text first; locale decimal commas

Before any cleaning, normalise: confirm the time column and whether it resets each step, standardise current/voltage units, and keep the step/cycle index — you need it to clean per step rather than across boundaries. Cleaning a current channel across a step transition is how you accidentally flatten a real CC/CV corner.

Step-by-step cleaning

import pandas as pd
from scipy.signal import medfilt

df = pd.read_csv("cell_01.csv")          # after unit/format normalisation
# 1) de-spike current within each step (median filter is spike-robust)
df["I"] = df.groupby("step")["I"].transform(lambda s: medfilt(s.values, 5))
# 2) fill short logger dropouts by time, not by row
df = df.set_index("t").interpolate(method="time").reset_index()
# 3) keep the slow channels lightly smoothed — see the dQ/dV caution below

The dQ/dV caution

The whole point of the test is the slow change — capacity fade and the shape of the voltage curve. A wide moving average quietly shaves the peaks of a dQ/dV plot and can make two different cells look identical. The rule: de-spike aggressively (spikes are not signal), but smooth the slow channels with a light touch and a do-no-harm criterion that backs off where the curve is already smooth. Always overlay before/after and confirm the fade curve is untouched and coulombic efficiency has not shifted.

Doing it across a whole campaign

One file is a script; a campaign of hundreds of cells across two or three cyclers is a maintenance burden — a new export template silently breaks your parser, and each format needs its own rules. That is the case for treating cleaning as a service: ingest the export, de-spike and gap-fill every column, preserve the fade curve, and get a clean CSV back without a per-format script to babysit.

FAQ

How do I remove current spikes from cycler data?

De-spike within each step using a median filter (scipy medfilt) so a real CC/CV corner is not flattened. Never de-spike across a step transition.

Will cleaning change my capacity or dQ/dV curve?

It should not. De-spike hard, but smooth slow channels lightly with a do-no-harm criterion, and always overlay before/after to confirm the fade curve and dQ/dV peaks are preserved.

Can I clean Arbin, Neware, Maccor and BioLogic the same way?

The cleaning logic is the same, but each exports different units, columns and time conventions, and BioLogic .mpr must be converted first. Normalise format and units before cleaning.

Skip the code. Drop your CSV into the free browser demo — no sign-up — and get a denoised, gap-filled, de-spiked file back in a minute. Every column, priced by volume when you need more. See the tool →