Guide
How to Save a Pandas DataFrame to CSV Without the Index
Open a fresh export in Excel and the first column is a run of numbers nobody asked for — 0, 1, 2, … in front of name, age,city. That column is the DataFrame's index, and pandas writes it becauseto_csv() defaults to index=True.
One argument turns it off:
df.to_csv("output.csv", index=False)index=False is a write-time switch. It decides what lands in the file and changes nothing about the DataFrame in memory — writing pandas to CSV without the index is a matter of overriding that one default. The converter below opens with exactly this configuration — download the file or copy the call it generates.
Why pandas adds an index column
Every DataFrame has an index — the labels down the left side when you print it. For a freshly built frame it is a RangeIndex: 0 through n−1, generated for you. When pandas serialises to CSV it writes those labels as the first column, because dropping data silently would violate the same principle that keepsread_csv() able to round-trip a file. The signature says so plainly:index=True.
The consequence is that the index column arrives whether it carries meaning or not. When the labels are dates, IDs or categories, that column is the point. When they are a forgotten RangeIndex, it is noise that breaks the next import — a colleague's script reads it as a column named Unnamed: 0, or the sheet simply looks wrong.
Before and after: what index=False changes
Written with pandas defaults — header row plus index column:
,name,age,city
0,Alice,25,Delhi
1,Bob,30,Mumbai
2,Charlie,28,ChandigarhWritten with index=False:
name,age,city
Alice,25,Delhi
Bob,30,Mumbai
Charlie,28,ChandigarhThe data rows are identical. The only difference is whether the labels travelling with the frame are carried into the file — and the empty header cell that goes with them.
Try it in the converter
The tool opens with the sample above and the index turned off, so the preview and the generated code already show the file you want. Tick Add row numbers to reproduce the problem — the extra column appears in the preview and in the download — then untick it. The call updates live; copy it straight into your script.
Add your data
You can also paste data copied from a spreadsheet.
Your data stays in your browser. Nothing is uploaded.
CSV options
to_csv() parameter, and the defaults are tuned for clean CSV output.More options— formatting, columns, quoting, line endings
Your CSV is ready
| name | age | city |
|---|---|---|
| Alice | 25 | Delhi |
| Bob | 30 | Mumbai |
| Charlie | 28 | Chandigarh |
Showing all 3 rows.
Long values are clipped to keep rows readable — hover to see full cell. The downloaded output.csv contains every value in full.
Pandas code
df.to_csv() call that reproduces these settings in Python.df.to_csv("output.csv", index=False)Assumes your DataFrame is named df and that pandas is already imported.
Everything runs in this tab. Nothing is uploaded — the CSV you download is assembled here.
Four fixes for an unwanted index column
Fix 1 — write the file with index=False
The fix for the export itself. Put index=False in the call that writes the file and the column never reaches it:df.to_csv("output.csv", index=False). For a pandas-to-CSV export without the index, this single argument is the whole fix — and it is the only one most code needs.
Fix 2 — remove the index from the DataFrame with reset_index(drop=True)
Use this when the index should not exist anywhere — not in the file and not in the frame your next line of code touches:
df = df.reset_index(drop=True)
df.to_csv("output.csv", index=False)The distinction matters: index=False changes only the file;reset_index() changes the DataFrame. And callingreset_index() without drop=True does the opposite of removing the index — it pushes the old labels into a new column, so writing afterwards can hand you the data twice. drop=True is what actually discards them.
Fix 3 — clean up a CSV that already has the column
The file on disk already contains the stray first column. Read it back into the index and rewrite without it:
df = pd.read_csv("output.csv", index_col=0) # first column back into the index
df.to_csv("output.csv", index=False) # rewrite, this time without itIf the column was never an index to begin with — it is simply junk — drop it by name. pandas names an unnamed header cell Unnamed: 0 on the way back in, sodf.drop(columns=["Unnamed: 0"]) removes it anddf.to_csv(..., index=False) keeps it gone.
Fix 4 — keep the index, but name it
Sometimes the column is right and only the empty header cell is wrong. Name it instead of deleting it:
df.to_csv("output.csv", index_label="row_id")index_label only applies when the index is being written, so it combines withindex=True (the default) and never with index=False. The same control sits in the converter under More options → Index column name.
When you should keep the index
If the labels are real data — timestamps, order IDs, a date-indexed series — write them. The file should carry them, and the reader should be told how to get them back:
df.to_csv("output.csv") # index=True keeps the labels
back = pd.read_csv("output.csv", index_col=0) # restored on the way inTurn index=False on that frame and the round trip silently degrades: the file has no labels, so read_csv() builds a fresh RangeIndex from 0. The numbers may look identical — the original identity of each row is gone. Keep the index when it means something; drop it when it is just a counter.
Common mistakes
- Calling
reset_index()withoutdrop=Trueand expecting the column to vanish. It moves the index into a column instead, and the default write can then produce two extra columns where you started with one. - Turning the index off once and assuming it is off for good.
index=Falsebelongs in every writing call — it is not a setting on the DataFrame. Keep it in the function that exports, not in an interactive edit. - Hand-deleting the column in Excel after each export. The file will be regenerated the same way every time; fix the call that writes it.
- Renaming
Unnamed: 0after the fact. That works once, butindex_labelprevents the unnamed cell from existing in the first place. - Assuming
index=Falsesurvives the round trip. The labels are not in the file, so reading it back cannot restore them — write them when you need them later.
Frequently asked questions
Why does my CSV have an extra column of numbers?
Because to_csv() writes the DataFrame index by default: pandas sets index=True in the signature. With a plain RangeIndex that shows up as an unnamed first column of 0, 1, 2, … sitting in front of your real data.
Does index=False change my DataFrame?
No. It only changes what is written to the file. The DataFrame in memory keeps its index, so a later export without index=False will put the column straight back — the fix belongs in the call, not in a one-off edit.
What's the difference between index=False and reset_index()?
They act at different layers. index=False keeps the index in the DataFrame and leaves it out of the file. reset_index() moves the index into the DataFrame as a regular column — so writing afterwards with pandas defaults can give you the data twice. Use reset_index(drop=True) when you want the index gone from the DataFrame as well as the file.
How do I remove the index column from a CSV I already saved?
Read it back with the column pulled into the index, then rewrite: df = pd.read_csv("output.csv", index_col=0) followed by df.to_csv("output.csv", index=False). If the file was never meant to have that column at all, drop it by name instead: df.drop(columns=["Unnamed: 0"], inplace=True).
How do I keep the index but give it a name?
Pass index_label: df.to_csv("output.csv", index_label="row_id") writes row_id as the header of the index column instead of leaving the first header cell empty.
Why is my index gone after reading the file back?
A CSV written with index=False does not contain the original labels. pd.read_csv() builds a fresh RangeIndex numbered from 0. If the index matters, write with index=True and read with pd.read_csv("output.csv", index_col=0) to restore it.
Related guides
- How to save a Pandas DataFrame to a CSV file — the full
df.to_csv()workflow: filenames, folders, columns, encoding. - How to append to a CSV file with Pandas —
mode="a"againstmode="w", and the header trap. - Common Pandas to CSV examples — ten worked calls, including this one, on the home page.
Reviewed against the pandas 3.0.6 DataFrame.to_csv() reference — 6 October 2026.