deepset-ai / deepset-ai/haystack
CSVDocumentCleaner deletes a row that says N/A, and both CSV components empty those cells
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 26.6k
- Forks
- 3.2k
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 194
Description
Describe the bug
CSVDocumentCleaner deletes a row whose cells say N/A, and both it and CSVDocumentSplitter empty any cell holding one of pandas' default missing-value strings.
pd.read_csv treats the literal strings N/A, NA, n/a, NULL, None, NaN and nan as missing values. Neither component passes keep_default_na=False, and dtype=object does not change it — the string is gone before the dtype is applied. CSVDocumentCleaner then runs dropna(how="all") over those rows, so a row that says "not applicable" in every column is treated as an empty row and removed.
Error message
None. No error, no warning — the document simply comes back smaller.
Expected behavior
A cell that says N/A is a cell with content. N/A is how a person writes "not applicable" and NULL is what a database export writes, so those cells usually carry the answer someone would ask the document for. They should survive cleaning and splitting; only genuinely empty cells should count as empty.
Additional context
Measured on main (7476cef):
from haystack import Document
from haystack.components.preprocessors.csv_document_cleaner import CSVDocumentCleaner
# 1. a row that says N/A everywhere is deleted
csv = "Code,Status\nA1,ok\nN/A,N/A\nA3,ok\n"
CSVDocumentCleaner().run(documents=[Document(content=csv)])["documents"][0].content
# -> 'Code,Status\nA1,ok\nA3,ok\n' the middle row is gone
# 2. a column of statuses is emptied
csv = "Code,Status,Note\nA1,N/A,keep\nA2,NULL,keep\nA3,NA,keep\n"
CSVDocumentCleaner().run(documents=[Document(content=csv)])["documents"][0].content
# -> 'Code,Status,Note\nA1,,keep\nA2,,keep\nA3,,keep\n'
CSVDocumentSplitter produces the same emptied content for case 2.
The fix is one merged default in each component, keeping the caller's override intact:
# cleaner
df = pd.read_csv(StringIO(document.content), header=None, dtype=object, keep_default_na=False)
# splitter
resolved_read_csv_kwargs = {
"header": None, "skip_blank_lines": False, "dtype": object,
"keep_default_na": False, **self.read_csv_kwargs,
}
A genuinely empty cell is unaffected — keep_default_na governs only the string list, not real blanks — so remove_empty_rows / remove_empty_columns keep doing their job.
I have this reproduced with tests and would normally open the PR, but the flood guard on my last PR asks me to hold off until the first two of my open ones are reviewed, so this is the report instead. Say the word and I will send it.
To Reproduce
The two snippets above, against main.
FAQ Check
- Have you had a look at our new FAQ page?
System:
- OS: macOS
- Haystack version:
mainat7476cef - Reproduced with the installed
pandasfrom the dev extras
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with haystack/components/preprocessors/csv_document_cleaner.py and the CSVDocumentSplitter entry point, then run the two reproductions in the issue to observe how pandas parses N/A-like strings. Check the existing component tests and add regression coverage for both cleaning and splitting. Done means literal missing-value strings survive while genuinely empty cells are still handled as empty.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- pandas, python
- Domain
- data
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100