How to Preserve Blanks, True Zeros, and Missing Data
Preserve confirmed zeros, convert only documented missing markers, and disclose ambiguous blanks before publishing or sharing a dataset.

Retain 0 when it is a confirmed value. Classify a blank, NA, NULL, -999, or another sentinel as missing only when the dataset’s codebook or provenance supports that interpretation. CSV records fields and delimiters, but it does not establish whether an empty field means unknown, unavailable, not applicable, or intentionally empty text.
If the source meaning cannot be verified, preserve the original representation and disclose the ambiguity. Do not guess, impute, or silently replace it.
Related: Accessible Data Table Captions and Summaries: How to Write Them.
The short answer: do not infer meaning from the cell alone
A numeric zero, empty text, and a missing observation are different concepts:
- Numeric zero (
0) is a number. It may represent a measurement or confirmed count. - Empty text is a string containing zero characters. It may appear in a CSV as a quoted empty field, although that spelling has no universal dataset-level meaning.
- Missing means that no value was recorded. The reason might be unknown, not reported, not collected, not applicable, or withheld.
A dataset may define 0 as a missing-value sentinel, but that is a dataset-specific convention—not an inherent property of zero or CSV. Convert zero to missing only when the relevant codebook, methodology, source system, or data owner establishes that meaning for the particular column.
Bare CSV cannot resolve these questions. It has no native mechanism for declaring column types, required-value rules, or the semantic meaning of blanks. The explanatory W3C CSV on the Web primer describes how separate metadata can document structure and support validation. The primer is guidance; the associated CSVW recommendations provide the technical model.
A row can also be structurally valid while containing empty cells. Structural validity shows that the row has the expected arrangement of fields, not whether an empty cell is permitted or what it means. The W3C tabular data model separates table structure from metadata and annotations while allowing structurally consistent rows to contain empty cells.
Use a decision table before changing any values
Make decisions per column rather than applying file-wide replacements. The same token can have different meanings in different fields.
| Source representation | Possible meaning | Default preservation decision | Documentation needed |
|---|---|---|---|
0 |
Confirmed zero, measurement, or sentinel | Preserve as zero | Whether zero is valid or a declared sentinel |
Empty field, such as 12,,West |
Missing, unknown, or intentionally blank | Preserve until verified | Column definition and missing-value convention |
Quoted empty field, such as 12,"",West |
Empty text or another serialized empty field | Preserve the source representation | Export rules and parser behavior |
-999 |
Legitimate value or sentinel | Preserve unless declared missing | Valid range and sentinel definitions |
NA, NULL, or similar text |
Literal text, category, or missing marker | Convert only when declared missing | Per-column marker definitions |
| Entirely blank line | Separator, artifact, or malformed record | Inspect as a structural case | File-generation rules |
| Row with too few fields | Truncated or irregular record | Quarantine or investigate | Expected field count |
Consider this synthetic file:
area,incident_count,note
North,0,confirmed
South,,not reported
East,-999,legacy marker
West,"",reviewed
Central,4
These records require separate decisions:
Northshould retain0if it is a confirmed count.Southcontains an empty field whose meaning requires documentation.Eastshould become missing only if-999is a declared sentinel forincident_count.Westcontains quoted empty text, but a parser may not retain its distinction from an unquoted empty field.- The blank line is a row-level structural case.
Centralhas fewer fields than the header defines.
Do not process these cases with one global replacement rule. Diagnose source meaning, cell-level absence, and row structure separately.
Separate source meaning, CSV serialization, and parser behavior
Two tools can interpret the same file differently because three layers are involved:
- Source semantics: what the producer intended each value or marker to mean.
- CSV serialization: how field text, delimiters, line endings, and quotation marks were written.
- Importer behavior: how software maps parsed content into strings, numbers, dates, or null-like values.
Importer settings control the third layer. They cannot discover the first. Configuring a tool to convert -999 into a missing value does not prove that the producer intended -999 to mean missing.
Quoted and unquoted empty fields also lack universally distinct meanings. A particular workflow may define "" as intentional empty text and ,, as unknown, but that convention must be documented and supported throughout the pipeline.
In one reported Python csv.reader workflow, quoted and unquoted empty fields were both returned as empty strings. That community example illustrates how a quoting distinction can disappear during ordinary parsing; it does not establish the behavior of every parser or configuration.
Once a meaningful distinction has been erased, a later export or metadata file cannot reliably reconstruct it. Retain the original file when quotation or exact source spelling matters, and test the chosen parser before relying on those details.
Avoid placeholder-based textual replacement as a general fix. Replacing "" before parsing may interact badly with escaped quotation marks, multiline fields, alternate delimiters, or genuine values matching the placeholder. Use a CSV-aware parser and a controlled data model instead.
Configure pandas without turning true zeros into missing data
The following behavior is specific to the documented pandas 3.0.6 interface. Other versions, parser engines, and CSV tools may behave differently.
By default, pandas.read_csv() recognizes empty strings and a documented set of textual tokens—including forms such as NA, NaN, N/A, and NULL—as missing values. Numeric zero is not in that default list. The parameters dtype, na_values, keep_default_na, na_filter, and skip_blank_lines control different aspects of import behavior in the pandas 3.0.6 read_csv documentation.
If a codebook says that blank incident_count fields and -999 are missing while text fields should retain their strings, configure the affected column deliberately:
import pandas as pd
df = pd.read_csv(
"incidents.csv",
dtype={
"area": "string",
"incident_count": "Int64",
"note": "string",
},
keep_default_na=False,
na_values={
"incident_count": ["", "-999"],
},
skip_blank_lines=True,
)
This configuration:
- Declares expected column types.
- Preserves numeric
0. - Disables pandas’ default textual missing-value list.
- Treats only the declared markers in
incident_countas missing.
Use “missing” as the general concept rather than assuming one scalar representation.
With keep_default_na=False and no na_values, pandas does not parse strings as missing values. That setting can help with preservation-oriented inspection, although columns containing blanks or markers may remain textual.
Setting na_filter=False disables missing-value detection entirely. Pandas then ignores keep_default_na and na_values.
An empty field is not the same structural case as an entirely blank line. With skip_blank_lines=True, blank lines are skipped rather than imported as rows of missing values. Under particular documented index-inference behavior, a row with fewer fields than an earlier row may have absent fields filled with a missing value. Test the exact version, parser engine, and settings rather than assuming every short row will be handled identically; the pandas I/O guide documents these controls.
Avoid indiscriminate numeric coercion. pandas.to_numeric(..., errors="coerce") converts invalid numeric text to a missing value. Applied without review, it can conceal misspellings, unexpected units, shifted fields, or corrupted records.
Preserve meaning through cleaning and export
Use a preservation-first workflow:
- Retain the unchanged source. Keep it separate from working and publication files.
- Find the codebook or provenance. Contact the data owner when definitions remain unclear.
- Define rules per column. Record types, valid ranges, zero semantics, missing markers, and permitted blanks.
- Configure the importer. Avoid defaults that conflict with the documented convention.
- Inspect the parsed result. Review suspicious records before replacement or conversion.
- Export the publication file. Retain transformation code or a written transformation log.
- Re-import the export. Validate the file that readers will receive.
For affected columns, record counts at the source, parsed, cleaned, and re-imported stages:
- Numeric zeros
- Empty strings or fields
- Each declared sentinel
- Parsed missing values
- Invalid or unexpected entries
Also compare row and column counts, expected field counts, declared or inferred types, and invalid numeric or date values. A changed count is not automatically an error, but it should reconcile with a documented transformation. If 24 occurrences of -999 become 24 missing values, that change is explainable. If the zero count falls unexpectedly, stop and investigate.
Test empty cells, blank lines, and short rows independently because importers may skip, fill, reject, or reshape them differently. These are practical publication checks, not requirements imposed by CSV or CSVW.
If several reasons for absence matter, consider a companion status field:
area,incident_count,incident_count_status
North,0,reported
South,,not_reported
East,,not_collected
West,,withheld
This optional model keeps the measurement column numeric while preserving distinctions that one null-like value cannot express. Define the allowed status codes and validate their combinations.
Document absence before publishing the dataset
Readers should not have to reverse-engineer blank cells. Publish a data dictionary or methodology note describing each affected column.
| Field | What to document |
|---|---|
| Column name | Exact CSV header |
| Type | Numeric, text, date, boolean, or another declared type |
| Required | Whether every record should contain a value |
Meaning of 0 |
Confirmed zero, valid value, or documented sentinel |
| Missing markers | Exact source and publication representations |
| Status codes | Definitions for absence or quality categories |
A worked entry might read:
incident_count— Integer; not required.0means a confirmed count of zero incidents. A blank means no count was reported. The reason for absence appears inincident_count_statusasnot_reported,not_collected,not_applicable, orwithheld.
Add a human-readable provenance note covering the source, codebook, cleaning decisions, transformations, and unresolved ambiguity.
CSVW metadata can supplement that note with machine-readable descriptions, table structure, expected values, and validation constraints. For a single CSV, the W3C primer describes a metadata filename formed by appending -metadata.json to the CSV filename—for example, incidents.csv-metadata.json (W3C CSV on the Web primer). Metadata can document intended interpretation, but it cannot restore distinctions erased during parsing or cleaning.
The resulting file and documentation can support an interpretable public data page. TablePage publishes spreadsheets as public interactive data pages, but publishers should still inspect the final page and downloadable file rather than assuming a publication platform will infer undocumented missing-value conventions.
Pre-publication checklist
- [ ] Confirm the documented meaning of blanks, zero sentinels, and textual missing markers.
- [ ] Preserve confirmed numeric zeros.
- [ ] Retain an unchanged source file.
- [ ] Document every transformation.
- [ ] Set column types and missing-marker rules explicitly.
- [ ] Inspect empty cells, blank lines, short rows, and unexpected field counts separately.
- [ ] Review invalid numeric text before coercing it to missing.
- [ ] Compare zero, sentinel, invalid-value, and missing-value counts before and after cleaning.
- [ ] Export and re-import the final CSV.
- [ ] Confirm row counts, column counts, types, and field counts after the round trip.
- [ ] Publish a data dictionary or methodology note.
- [ ] Explain unresolved ambiguity instead of silently replacing uncertain values.
- [ ] Use synthetic or already-public examples for testing.
- [ ] Review the final public representation without assuming unverified platform behavior.
Frequently asked questions
Does a blank CSV field automatically mean null?
No. A blank field has no visible content, while “null” or “missing” is an interpretation applied by a data model or importer. Consult the codebook or provenance. If no definition exists, preserve and disclose the ambiguity.
Does pandas treat zero as a missing value?
Not by default in pandas 3.0.6. Numeric zero is absent from the documented default missing-value markers. Custom na_values, converters, replacements, or later coercion can still transform it, so validate zero counts after import and export (pandas read_csv documentation).
Are "" and an unquoted empty field guaranteed to remain different?
No. A producer may assign them different meanings, but that distinction is not universal. Some parsers or cleaning workflows may return both as the same empty string. If the difference matters, document it, retain the original file, and test the complete import and export path.
Can CSVW metadata restore distinctions lost during cleaning?
No. CSVW metadata can describe table structure, expected values, required fields, and intended interpretation, but it cannot reconstruct whether a collapsed value was originally quoted, unquoted, withheld, unknown, or intentionally empty.
The durable rule has three parts: preserve confirmed zeros, never guess what a blank means, and make missing-value conventions explicit before publication. Keep the raw file, validate the cleaned CSV through an export-and-re-import round trip, and publish a data dictionary or provenance note with the public dataset.