Guide · spectroscopy data in Python

Combine Raman spectra into one file

Two hundred measurements, one per sample, and your PCA, your cluster plot, or your supervisor wants one dataset. Here is the shortest honest path for each situation, including the case everyone hits sooner or later: the files do not share the same wavenumber grid.

1. Same grid, same export layout: pandas concat

If every CSV has the same two columns and the same axis points, a ten-line script is enough:

import glob, os
import pandas as pd

frames = []
for f in glob.glob("exports/*.csv"):
    df = pd.read_csv(f, sep=None, engine="python", comment="#").iloc[:, :2]
    df.columns = ["wavenumber", "intensity"]
    df["sample"] = os.path.basename(f)
    frames.append(df)

combined = pd.concat(frames, ignore_index=True)   # tidy long format

This works until it doesn't. The quiet failure modes:

SymptomCauseWhat the script does
NaN everywhere after pivotinggrids differ by one point or rangesilently misaligns
Values look shiftedone file in nm, another in cm-1merges different units
Sample names lostnames lived in a header line or a metadata filedrops them
Half the folder missingsemicolon or tab exports, comment headersparses wrong

2. A real folder: convert once, get one table per modality

eQCX converts the whole folder into the open eQC format: one spectra.csv per modality (rows = axis points, columns = samples) plus metadata.csv linked by sample_id. That single table is the combined file, and it loads in three lines:

import eqc, pandas as pd

g = eqc.read("my_eqc_output")[0]              # first modality group
spectra = pd.DataFrame(g.samples, index=g.axis)   # rows = axis, cols = samples
meta = pd.DataFrame(g.metadata)                    # sample_id + every detail
One line to Excel: spectra.T.to_excel("all_samples.xlsx") (pandas writes xlsx through openpyxl). Or just open spectra.csv in Excel directly.

Because the columns are sample ids linked to metadata rows, group labels, concentrations, or instrument details travel with the data. No filename parsing, no side tables.

3. Spectra that don't share the grid

Different lasers, different instruments, different export menus: the ranges and point spacing will not match. eQCX never invents points and never intersects grids, so by default spectra with different ranges go to separate output files instead of a corrupted merge. When you need one shared axis for the whole set, the opt-in unification merges them:

ChoiceWhat it does
Majoritypicks the axis most samples already share, so most spectra need no maths at all
Finestadopts the densest axis
Canonicalyour own min, max, and step

Interpolation is linear, PCHIP, or Lanczos, a fidelity guard warns if a resampled spectrum drifts from its measured shape, and the merge is logged with an alteration report. Measured values stay untouched unless you ask for this step by name.

Which route fits you?

SituationRoute
20 files, one instrument, same exportpandas concat (route 1)
A real folder: mixed layouts, metadata in siblingseQCX conversion (route 2)
Different grids or ranges, need one axisroute 2 + opt-in unification
The group wants one Excel fileroute 2, then open spectra.csv or one to_excel line

Questions people ask

How do I merge multiple Raman CSV files into one dataset?

Same grid: pandas concat with a sample column. Different layouts or grids: convert the folder once with eQCX and load the single spectra table.

Can I get everything into one Excel file?

spectra.csv opens in Excel as-is, or spectra.T.to_excel("all_samples.xlsx") writes it from pandas.

My spectra have different wavenumber ranges. Will they be padded with NaN?

No. They go to separate output files by default. The opt-in unification merges them onto one axis with a fidelity guard and a logged alteration report.

Do I have to parse filenames to keep sample names?

No. After conversion every column is a sample_id linked to a metadata row; names and groups come from the metadata table.

One folder in, one combined table out.

eQCX runs on Windows and processes everything locally. Free with a university email.

Download for Windows

Coming from Bruker? Read Convert Bruker CSV to Python first. Full docs: the wiki