🧹 Data Cleaning · 7 min read
How Do I Remove a Column From a CSV File?
Remove the field from the header line and from every data line in the same pass, so all lines keep the same field count; a CSV stores no column names anywhere except the header, and readers match values to columns by position.
That is the whole rule, and every way of breaking a file ignores part of it. The header edited alone leaves one extra field at the top. The body edited alone leaves the header describing a column that no longer exists. A tool that splits on commas without reading quotes removes half a field and leaves a stray quote behind. The rest of this page is the three methods that do it properly, and the measurements behind the failure modes.
Quick answer
For an empty column, use the CSV cleaner, which removes empty rows and empty columns. For a named column, rewrite the file with a csv-aware reader and writer, or df.drop(columns=[...]) in pandas. Use cut or awk only when you have confirmed that no field contains a quoted comma. Never edit one side of the file by hand.
The failure mode, measured
Start with a file whose header has three fields and whose last row has two. This is what a partial delete looks like, and it is the shape that quietly corrupts a report.
id,name,note
1,Ann,ok
2,Bo
pandas reads it without complaint and pads the short row: the note column becomes NaN for Bo. The csv module is more honest and returns a row of length two next to rows of length three.
| Reader | What it returns | Would you notice? |
|---|---|---|
pandas read_csv | a valid frame, missing value filled as NaN | only by looking at the column |
Python csv.reader | field counts of 3, 3, 2 | yes, if you print the counts |
| Positional consumer (SQL load, script) | the wrong value under the wrong header from that row on | no, and it propagates |
The third row is the reason this matters. A file with an inconsistent field count is not rejected by most loaders, and the row that lost a field shifts every value after it into the neighbouring column. Counting fields per row is the cheapest check there is: the analyzer shows the count per row next to the header.
Method 1: remove an empty column with the CSV cleaner
When the column has no data in it at all, the removal is mechanical: drop the header field and the matching position in every row. The cleaner does exactly that, in the browser, with no upload.
One caution that costs people a column of real data: "empty" has to mean empty in every row, not in the rows you looked at. In this three-row file the third column is blank for two rows and populated in the third, so a check that sampled the top of the file would have called it empty and deleted a value.
a,b,c,d
1,x,,p
2,y,,q
3,z,7,r
Scan all rows and the answer is unambiguous: column c is not empty. Scan the first two and it looks empty. Any tool that offers to remove empty columns is making that choice on your behalf, so it is worth knowing that ours reads the whole file rather than a preview, and it is still worth checking the column yourself when the file is large enough that you cannot see the end of it.
Method 2: cut and awk, and where they stop working
Both commands split on a delimiter and count fields, which is exactly right for a CSV that never quotes anything. Here is a two-row file with one quoted comma in a name, run through the command most people reach for first:
$ cut -d, -f1,3 q.csv
id,note
1, John"
2, Ann"
The name was split on its internal comma, so field three was taken from inside the name and the closing quote stayed attached. awk -F, with the same output fields does the same thing, because -F sets a field separator and neither tool has a concept of quoting. RFC 4180 section 2 says fields containing commas should be enclosed in double quotes, which means a comma inside quotes is data, not a separator, and splitting on every comma is wrong for any file that follows the rule.
They are still usable when you know the shape of the data: drop a numeric ID column from an export you generated yourself, and there is nothing to quote. Check one line for " first, and if you find one, move to the next method.
Method 3: rewrite with a csv-aware reader
The standard library approach keeps quoting correct and lets you choose the surviving columns by name, in the order you want them. Output below is from the four-row order file used in our CSV to nested JSON walkthrough, with the item column dropped.
import csv
with open("orders.csv", newline="") as f:
rows = list(csv.DictReader(f))
keep = ["order_id", "customer_name", "customer_email", "qty"]
with open("slim.csv", "w", newline="") as f:
w = csv.DictWriter(f, fieldnames=keep, extrasaction="ignore")
w.writeheader()
w.writerows(rows)
extrasaction="ignore" is what makes this a removal rather than an error: the reader returns every column as a dict key, and the writer keeps only the names listed in fieldnames. Because the writer re-quotes from scratch, a field that was quoted in the input may come back unquoted if it no longer needs quotes. That is legal CSV and identical data, but it is not a byte-identical edit, which matters if anything downstream compares files.
In pandas the same operation is one call, and the side effect to know about is the line ending:
import pandas as pd
df = pd.read_csv("orders.csv")
df.drop(columns=["item_sku"]).to_csv("slim.csv", index=False)
The same four records came out of pandas as 134 bytes with line feeds only, and out of the csv module as 138 bytes with CRLF, which is the line break RFC 4180 specifies. On Windows pandas writes CRLF instead, since the documentation says the terminator defaults to os.linesep. Both files open, but only one of them matches the original byte for byte.
How to find the column you actually want to drop
- Count the header fields first. If the header says 12 and the rows say 12, every method above is safe on the structure.
- Decide by name, not by position.Position is what breaks when an export adds a column at the front, which is how most "it worked last month" bugs start.
- Check for quotes in the column you plan to split around. A single quoted comma anywhere in the file rules out
cutandawk. - Verify the output has the field count you expect. Header minus one, on every line, before the file goes anywhere else.
If the column you are removing exists because two fields were merged, or because a spreadsheet export added a blank spacer, the cleanup usually does not stop at one column: cleaning dirty CSV data covers the blank rows and stray whitespace that tend to arrive with it, and removing blank rows is the companion job.
Frequently asked questions
How do I remove a column from a CSV file without breaking it?
Remove the field from the header line and from every data line in the same operation, so each line still has the same number of fields. RFC 4180 section 2 states that each line should contain the same number of fields throughout the file, and that is the only structural guarantee a CSV gives you. A column has no name or index stored anywhere else, so the header is the only record that it existed.
Why are my columns misaligned after deleting one?
Because the field was removed from some lines and not others, or because a field containing a quoted comma was split. In our test a file whose header had three fields and one row had two fields still loaded in pandas without an error, with the missing value filled as NaN, and the csv module returned a row of length two next to rows of length three. Any reader that indexes fields by position then puts the wrong value under the wrong header.
How do I remove the first column from a CSV?
In the standard library, read each row with csv.reader and write row[1:] back with csv.writer. With awk, $1 is the first field but only if no field contains a comma inside quotes. With pandas, df.drop(columns=[df.columns[0]]) or df.iloc[:, 1:]. Avoid deleting the characters before the first comma in a text editor unless you are certain that the first column is a sequence number with no quoted commas anywhere in the file.
How do I remove empty columns from a CSV?
Check every row before you trust the answer. A column that looks empty in the first rows can carry data further down: in our three-row test, a column was blank in rows one and two and held a value in row three, so any check that sampled the top of the file would have deleted real data. Our CSV cleaner removes empty rows and empty columns, and the same rule applies there: the decision is only safe when the column is empty everywhere.
Can I just delete the column in Excel and save?
You can, and the file will still be valid CSV, but the round trip through a spreadsheet rewrites values as well as structure. Excel's grid holds 1,048,576 rows and 16,384 columns according to Microsoft's specifications page, so a wider file is truncated before you touch it, and saving can turn a code like 007 into 7 or a long number into 1.23E+15. If the column you are removing is the only reason you opened the file, cut it without opening it.
Do cut and awk work on CSV files?
Only on files where no field contains a comma inside quotes. cut splits on a single character and awk with -F, splits on a pattern; neither knows about the quoting rule in RFC 4180 section 2, which lets a quoted field contain commas. On a file with the name Smith, John in quotes, both commands returned a mangled third field ending in a stray double quote, while a csv-aware reader returned the three correct fields.
Does rewriting the file change its line endings?
It can. RFC 4180 specifies CRLF as the line break, and the standard library writer reproduces that when the output file is opened with newline, while pandas to_csv writes the platform separator, documented as os.linesep. On Linux the same four records came out of pandas as 134 bytes with line feeds only, and out of the csv module as 138 bytes with CRLF. Readers usually accept both, but a checksum or a byte comparison against the original will not match.
Drop the Empty Columns First
Paste the file and remove empty rows and empty columns in one pass, before any script touches it.
The field-count rule and the quoting rule are from RFC 4180, section 2, as is CRLF as the record separator. The 1,048,576-row and 16,384-column grid figures are from Microsoft's Excel specifications and limits page. The os.linesep default for to_csv is stated in the pandas documentation for DataFrame.to_csv. Every command output and byte count on this page was produced on 2026-11-02 with Python 3.13.5, pandas 2.3.3 and GNU coreutils on Linux; the files were four rows long, so the numbers are small on purpose and you can reproduce them in a minute.
Related reading
Data Cleaning — other guides that pair well with this one.
Browse all guides in the NoCodeCSV blog.