Your recording, as numbers.
Convert EEG and biosignal files to CSV in one command.
See what is in the file before you write 108 MB of it
An eight hour sleep study at 100 Hz becomes three million rows. Run it with --info and the tool reads only the header, prints the channel table, estimates the output, and writes nothing.
$ edf2csv sleep-study.edf --info File sleep-study.edf Format EDF+ (continuous) Recorded 2002-03-02 23:10:00 Duration 8h 00m 0s (28,800 records of 1s) Size 18.7 MB Patient X X X X Recording Startdate 02-MAR-2002 X X X Channels 5 signals + 1 annotation channel # COLUMN LABEL UNIT RATE RANGE OUTPUT 0 EEG Fpz-Cz EEG Fpz-Cz uV 100 Hz -250 to 250 signals_100hz.csv 1 EEG Pz-Oz EEG Pz-Oz uV 100 Hz -250 to 250 signals_100hz.csv 2 EOG horizontal EOG horizontal uV 100 Hz -250 to 250 signals_100hz.csv 3 Resp oro-nasal Resp oro-nasal V 10 Hz -1 to 1 signals_10hz.csv 4 Temp rectal Temp rectal degC 1 Hz 34 to 40 signals_1hz.csv Sampling rates differ, so channels are written to 3 files, one per rate. No channel is resampled. Would write 3,196,800 rows, roughly 108 MB, and annotations.csv. warning: Channels use 3 different sampling rates (100 Hz, 10 Hz, 1 Hz). They are written to one file per rate so no channel is resampled. warning: At least one output file will have more than 1,048,576 rows, which is more than Excel or Numbers can open. Use --start and --duration to convert a section, or read the file with pandas or R.
It will not invent samples that were never recorded
EDF files routinely mix rates: EEG at 100 Hz next to a thermistor at 1 Hz. One wide table cannot hold both without making the slow channel up, so each rate gets its own file instead.
edf2csv writes exactly these three rows to signals_1hz.csv.
Average that column, count its samples, or plot it, and the numbers are not the ones the thermistor produced. No warning is issued.
What lands on disk
A directory named after the recording. Pick a file to see what is inside it.
One file per sampling rate
The three channels recorded at 100 Hz share a time base, so they share a table. Column names are the labels the file itself uses, spaces and all.
time_s,EEG Fpz-Cz,EEG Pz-Oz,EOG horizontal 0.000,0.061,0.061,0.061 0.010,1.648,1.404,0.916
Checked against the reference reader
Values are compared against pyEDFlib, the reader most of the field already trusts. Not close to it. Identical to it, down to the last bit of the double.