科技 · 實用指南
pandas 替 CSV 欄名加上 .1?刪欄前先保留位置對照
帶後綴的名稱可能是重名處理,也可能本來就存在。先讀原始表頭並保留位置,再重新命名、篩選或刪除。

不要因為 pandas 在某些欄名加入後綴,就刪掉所有以 .1 結尾的欄。原始檔可能已有合法名稱 a.1。DataFrame 欄名唯一不代表原表頭唯一。
我們用 Python 3.12.14 與 pandas 2.2.3 的小型測試中,a,a,a.1 變成 a,a.2,a.1,三個值仍在。若先經 csv.DictReader,重複 a 鍵只保留後面的值,這是另一種轉換。
以有序串列讀取原始表頭
先使用 import pandas as pd。保留原 CSV 位元組。對本文逗號分隔、單行表頭樣例,匯入 csv 與 io,再用 header = next(csv.reader(io.StringIO(text))),即可得到保留重名的有序串列。不要只看 pd.read_csv(..., nrows=0).columns,因為名稱已變更。
實際檔案需匹配分隔符號、引號、編碼與表頭位置。引號中的 "last,name" 是一個欄名,不能直接按逗號拆首個實體行。有前言、註解或多行表頭時,要先調整讀取程序。
重名不等於內容重複
樣例表頭 a,a,a.1 下一行為 10,20,30。預設欄名 a,a.2,a.1 中,第三欄原本就叫 a.1,第二個 a 才取得 a.2。移除後綴或依點加數字刪欄會破壞這個區別。
重名不能證明值一樣。同一樣例的 DictReader 得到 a='20'、a.1='30',先前的 10 已不在字典中。若上游轉字典丟失欄位,應回原 CSV;修改 pandas 欄名無法重建該值。
為每個位置建立唯一內部名稱
對受控單行表頭 CSV,建立 internal = [f'col_{i:03d}' for i in range(len(header))],並保存 list(enumerate(zip(header, internal)))。再讀 df = pd.read_csv(io.StringIO(text), header=0, names=internal, dtype=str, keep_default_na=False),以位置標識保留各欄。
實測 col_000、col_001、col_002 保留 '10'、'20'、'30';另一個首欄表頭含引號逗號的樣例也保留四欄。字串與缺失值設定針對這些文本樣例,實際型別政策另定,未約定時不要默默正規化空白或 Unicode。
選擇拒絕或明確映射,再驗證
若下游要求源欄名唯一,len(header) 與 len(set(header)) 不同就拒絕並報告重複位置。若重名刻意存在,要求資料負責人核准位置與含義的對照,不以方便的後綴自行取捨。
使用 usecols、改名或匯出前,核對欄數、映射與有差異的代表值。已安裝版本將 mangle_dupe_cols=False 視為未知參數,目前 API 亦無此項。只測試小型記憶體樣例,未測你的檔案或 pandas 3.x;請在部署版本複核並保留原件及映射。
