spark-mf4 (v2) — asammdf-backed Spark reader
v2 changes the approach. Instead of a hand-written MDF parser (v1, the Scala
data source), v2 delegates parsing to the mature asammdf
library and distributes the work across Spark. This reads the real-world files
(CANedge, Vector, ETAS, vendor variants) that a hand-written parser can silently
fail on — e.g. returning 0 rows — because asammdf handles the full spec.
How it works
Spark's built-in binaryFile source lists and reads each file as
(path, content) on any storage it supports (DBFS, Unity Catalog Volumes,
S3, ADLS, local). The bytes are handed to asammdf through an in-memory buffer
inside mapInPandas, so there's no dependence on a local filesystem path on the
executors, and files are read in parallel (one task per file).
binaryFile (path, content) ──► mapInPandas ──► asammdf.MDF(BytesIO(content))
└► pandas ─► Spark rows
Install (Databricks)
pyspark and pyarrow are already on the cluster. Install the library
(cluster Libraries → PyPI, or in a notebook):
%pip install spark-mf4 # once published; or: %pip install /Volumes/.../spark_mf4-2.0.0-py3-none-any.whl
Use
from spark_mf4 import read_mf4
# A single file, a directory, or a glob — all read in parallel.
df = read_mf4(spark, "/Volumes/main/default/logs/")
df.display()
# Options
read_mf4(spark, "s3://bucket/log.mf4", raster=0.1) # resample to 0.1 s
read_mf4(spark, ".../log.mf4", channel_group=0) # one channel group only
read_mf4(spark, ".../log.mf4", channels=["EngineSpeed"]) # subset of channels
Output columns: timestamp, one column per channel (names sanitised for Spark),
and source_file (the originating path; disable with add_source_column=False).
Options
| Option | Default | Meaning |
|---|---|---|
channels |
None |
Restrict to these channel names (whole file otherwise) |
channel_group |
None |
Read only this channel group (native time base) instead of the merged wide table |
raster |
None |
Resample to this many seconds |
time_from_zero |
False |
Shift timestamps to start at 0 |
add_source_column |
True |
Append the source file path as source_file |
path_glob |
*.{mf4,mdf,dat} |
Which files to pick up under a directory |
recursive |
True |
Recurse into sub-directories |
Notes
- Heterogeneous files in one
read_mf4call share the schema inferred from the first file; read files of the same type together. - CAN/LIN raw payloads come through as-is; DBC signal decoding (via
asammdf.extract_bus_logging) is a planned follow-up. - v1 (the pure-Scala
format("mf4")data source) remains onmain; v2 lives here underpython/.
Metadata
Release files for spark-mf4 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| spark_mf4-2.0.0.tar.gz | 6.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| spark_mf4-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.8 kB
Release files / spark_mf4-2.0.0.tar.gz
| Download URL | spark_mf4-2.0.0.tar.gz |
|---|---|
| Size | 6.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
314e7778991bccda2dda8a7ae5faaf1f328352766c1f2f95ac18c95c5ede12ba
|
|
BLAKE2b-256 checksum How to use checksums |
99e1e1b1463dec3a6250a3e13c527b0865bea4ed54320575b38a4167bad77123
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.2
|
Release files / spark_mf4-2.0.0-py3-none-any.whl
| Download URL | spark_mf4-2.0.0-py3-none-any.whl |
|---|---|
| Size | 6.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
241f1cfb2d6e62f2535b0c5803437980ba7650bd381fe06c9e9f0f47c50501c5
|
|
BLAKE2b-256 checksum How to use checksums |
6d29ddf7d823a0fce84d21bb8c43149d6e84c66700ed0eaf95da0eec1f21c47b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.2
|