[{"data":1,"prerenderedAt":2519},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-unnamed-0-columns-when-reading-excel":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-unnamed-0-columns-when-reading-excel":2483,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-unnamed-0-columns-when-reading-excel":2492,"children:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-unnamed-0-columns-when-reading-excel":2497,"related:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-unnamed-0-columns-when-reading-excel":2498},{"id":4,"title":5,"body":6,"dateModified":2448,"datePublished":2448,"description":2449,"extension":2450,"faq":2451,"keyword":2460,"kind":2461,"meta":2462,"navigation":341,"path":2471,"seo":2472,"slug":2475,"stem":2476,"topics":2477,"type":2481,"__hash__":2482},"docs\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-unnamed-0-columns-when-reading-excel\u002Findex.md","Fix \"Unnamed: 0\" Columns When Reading Excel with pandas",{"type":7,"value":8,"toc":2435},"minimark",[9,13,24,27,33,55,266,271,296,299,388,392,403,441,444,484,491,556,594,598,601,741,752,806,817,874,883,1077,1081,1094,1256,1263,1335,1342,1463,1471,1475,1486,1645,1648,1754,1762,1955,1959,1962,2246,2249,2253,2324,2328,2338,2342,2363,2367,2373,2379,2385,2395,2399,2431],[10,11,12],"p",{},"You read a workbook and the DataFrame arrives with columns you never created:",[14,15,21],"pre",{"className":16,"code":18,"language":19,"meta":20},[17],"language-text","['Unnamed: 0', 'region', 'sales']\n","text","",[22,23,18],"code",{"__ignoreMap":20},[10,25,26],{},"or, from a sheet someone built by hand, a scattering of them between the real headings:",[14,28,31],{"className":29,"code":30,"language":19,"meta":20},[17],"['id', 'name', 'Unnamed: 2', 'amount', 'Unnamed: 4', 'Unnamed: 5', 'Unnamed: 6']\n",[22,32,30],{"__ignoreMap":20},[10,34,35,36,39,40,43,44,48,49,54],{},"Nothing is broken. ",[22,37,38],{},"pandas.read_excel"," takes the header row literally, and whenever a header cell is empty it has to call the column something, so it uses ",[22,41,42],{},"Unnamed: "," plus the column's position. The fix depends on ",[45,46,47],"em",{},"why"," the header cell is empty, and there are four common reasons. This guide, part of ",[50,51,53],"a",{"href":52},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002F","Troubleshooting Common Python Excel Errors",", shows how to tell them apart and repair each one without losing data.",[56,57,65,66,65,70,65,74,65,82,65,88,65,98,65,103,65,114,65,120,65,126,65,129,65,135,65,139,65,143,65,147,65,151,65,155,65,160,65,164,65,166,65,170,65,172,65,175,65,178,65,182,65,184,65,187,65,189,65,193,65,195,65,198,65,201,65,205,65,207,65,209,65,211,65,214,65,216,65,219,65,227,65,232,65,239,65,247,65,253,65,258,65,262],"svg",{"viewBox":58,"role":59,"ariaLabelledBy":60,"xmlns":63,"style":64},"156 0 448 202","img",[61,62],"unn-where-t","unn-where-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:448px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[67,68,69],"title",{"id":61},"Where an \"Unnamed: 0\" column comes from",[71,72,73],"desc",{"id":62},"A worksheet written by to_excel with its default index. Cell A1 is empty because the index had no name, and column A holds the index values 0 and 1. read_excel names that column \"Unnamed: 0\".",[75,76],"rect",{"x":77,"y":78,"width":79,"height":80,"fill":81},"156","0","448","202","#ffffff",[19,83,87],{"x":84,"y":85,"style":86},"380.0","31.0","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","A file written with to_excel(path) — index included",[75,89],{"x":90,"y":91,"width":92,"height":93,"rx":94,"fill":95,"stroke":96,"style":97},"172.0","48.0","195.9","30.0","8","#e7ebef","var(--line,#cdd5e6)","stroke-width:1.5px",[75,99],{"x":90,"y":100,"width":92,"height":101,"rx":78,"fill":95,"stroke":96,"style":102},"70.0","8.0","stroke-width:0px",[104,105,107],"g",{"transform":106},"translate(182.0,55.0) scale(0.667)",[108,109],"path",{"d":110,"fill":111,"stroke":112,"style":113},"M6 3h9l4 4v14H6z M15 3v4h4 M9.5 11.5l4.5 6 M14 11.5l-4.5 6","none","var(--teal-ink,#0b6157)","stroke-width:2.70px;stroke-linecap:round;stroke-linejoin:round",[19,115,119],{"x":116,"y":117,"style":118},"204.0","68.0","font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:start","report.xlsx",[75,121],{"x":90,"y":122,"width":123,"height":124,"rx":78,"fill":95,"stroke":96,"style":125},"78.0","32.0","24.0","stroke-width:1px",[75,127],{"x":116,"y":122,"width":128,"height":124,"rx":78,"fill":95,"stroke":96,"style":125},"44.0",[19,130,134],{"x":131,"y":132,"style":133},"226.0","95.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[75,136],{"x":137,"y":122,"width":138,"height":124,"rx":78,"fill":95,"stroke":96,"style":125},"248.0","63.6",[19,140,142],{"x":141,"y":132,"style":133},"279.8","B",[75,144],{"x":145,"y":122,"width":146,"height":124,"rx":78,"fill":95,"stroke":96,"style":125},"311.6","56.4",[19,148,150],{"x":149,"y":132,"style":133},"339.8","C",[75,152],{"x":90,"y":153,"width":123,"height":154,"rx":78,"fill":95,"stroke":96,"style":125},"102.0","28.0",[19,156,159],{"x":157,"y":158,"style":133},"188.0","121.0","1",[75,161],{"x":116,"y":153,"width":128,"height":154,"rx":78,"fill":162,"stroke":163,"style":97},"#fee8f2","var(--accent,#f43f8f)",[75,165],{"x":137,"y":153,"width":138,"height":154,"rx":78,"fill":81,"stroke":96,"style":125},[19,167,169],{"x":141,"y":158,"style":168},"font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","region",[75,171],{"x":145,"y":153,"width":146,"height":154,"rx":78,"fill":81,"stroke":96,"style":125},[19,173,174],{"x":149,"y":158,"style":168},"sales",[75,176],{"x":90,"y":177,"width":123,"height":154,"rx":78,"fill":95,"stroke":96,"style":125},"130.0",[19,179,181],{"x":157,"y":180,"style":133},"149.0","2",[75,183],{"x":116,"y":177,"width":128,"height":154,"rx":78,"fill":162,"stroke":163,"style":97},[19,185,78],{"x":131,"y":180,"style":186},"font-size:12px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle",[75,188],{"x":137,"y":177,"width":138,"height":154,"rx":78,"fill":81,"stroke":96,"style":125},[19,190,192],{"x":141,"y":180,"style":191},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","North",[75,194],{"x":145,"y":177,"width":146,"height":154,"rx":78,"fill":81,"stroke":96,"style":125},[19,196,197],{"x":149,"y":180,"style":191},"410",[75,199],{"x":90,"y":200,"width":123,"height":154,"rx":78,"fill":95,"stroke":96,"style":125},"158.0",[19,202,204],{"x":157,"y":203,"style":133},"177.0","3",[75,206],{"x":116,"y":200,"width":128,"height":154,"rx":78,"fill":162,"stroke":163,"style":97},[19,208,159],{"x":131,"y":203,"style":186},[75,210],{"x":137,"y":200,"width":138,"height":154,"rx":78,"fill":81,"stroke":96,"style":125},[19,212,213],{"x":141,"y":203,"style":191},"South",[75,215],{"x":145,"y":200,"width":146,"height":154,"rx":78,"fill":81,"stroke":96,"style":125},[19,217,218],{"x":149,"y":203,"style":191},"388",[220,221],"line",{"x1":222,"y1":223,"x2":224,"y2":223,"stroke":225,"style":226},"376.0","117.0","408.0","var(--brand,#5b5cf0)","stroke-width:2px",[228,229],"polygon",{"points":230,"fill":231},"412.0,117.0 403.0,122.0 403.0,112.0","#5b5cf0",[75,233],{"x":234,"y":235,"width":236,"height":237,"rx":238,"fill":162,"stroke":163,"style":226},"418.0","53.0","170.0","128.0","12",[104,240,242],{"transform":241},"translate(491.0,66.0) scale(1.000)",[108,243],{"d":244,"fill":111,"stroke":245,"style":246},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4","var(--accent-ink,#be185d)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[19,248,252],{"x":249,"y":250,"style":251},"503.0","112.5","font-size:13.5px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","A1 is empty",[19,254,257],{"x":249,"y":255,"style":256},"132.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","the index had no name,",[19,259,261],{"x":249,"y":260,"style":256},"149.5","so read_excel calls",[19,263,265],{"x":249,"y":264,"style":256},"167.0","column A \"Unnamed: 0\"",[267,268,270],"h2",{"id":269},"prerequisites","Prerequisites",[14,272,276],{"className":273,"code":274,"language":275,"meta":20,"style":20},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas openpyxl\n","bash",[22,277,278],{"__ignoreMap":20},[279,280,282,286,290,293],"span",{"class":220,"line":281},1,[279,283,285],{"class":284},"sMTad","pip",[279,287,289],{"class":288},"srMev"," install",[279,291,292],{"class":288}," pandas",[279,294,295],{"class":288}," openpyxl\n",[10,297,298],{},"The examples build their own small workbooks, so every block can be run as written:",[14,300,304],{"className":301,"code":302,"language":303,"meta":20,"style":20},"language-python shiki shiki-themes github-light github-dark-high-contrast","import pandas as pd\nfrom openpyxl import Workbook\n\ndf = pd.DataFrame({\"region\": [\"North\", \"South\"], \"sales\": [410, 388]})\n","python",[22,305,306,322,336,343],{"__ignoreMap":20},[279,307,308,312,316,319],{"class":220,"line":281},[279,309,311],{"class":310},"s-kum","import",[279,313,315],{"class":314},"skGVy"," pandas ",[279,317,318],{"class":310},"as",[279,320,321],{"class":314}," pd\n",[279,323,325,328,331,333],{"class":220,"line":324},2,[279,326,327],{"class":310},"from",[279,329,330],{"class":314}," openpyxl ",[279,332,311],{"class":310},[279,334,335],{"class":314}," Workbook\n",[279,337,339],{"class":220,"line":338},3,[279,340,342],{"emptyLinePlaceholder":341},true,"\n",[279,344,346,349,352,355,358,361,364,367,370,373,376,378,381,383,385],{"class":220,"line":345},4,[279,347,348],{"class":314},"df ",[279,350,351],{"class":310},"=",[279,353,354],{"class":314}," pd.DataFrame({",[279,356,357],{"class":288},"\"region\"",[279,359,360],{"class":314},": [",[279,362,363],{"class":288},"\"North\"",[279,365,366],{"class":314},", ",[279,368,369],{"class":288},"\"South\"",[279,371,372],{"class":314},"], ",[279,374,375],{"class":288},"\"sales\"",[279,377,360],{"class":314},[279,379,197],{"class":380},"sP0c6",[279,382,366],{"class":314},[279,384,218],{"class":380},[279,386,387],{"class":314},"]})\n",[267,389,391],{"id":390},"cause-1-the-file-was-written-with-its-index","Cause 1 — the file was written with its index",[10,393,394,395,398,399,402],{},"This is the most common source, and the one in the diagram above. ",[22,396,397],{},"DataFrame.to_excel()"," writes the index by default. An unnamed ",[22,400,401],{},"RangeIndex"," goes into column A with nothing in A1, so reading the file back produces an extra column:",[14,404,406],{"className":301,"code":405,"language":303,"meta":20,"style":20},"df.to_excel(\"report.xlsx\")                     # index=True is the default\nprint(pd.read_excel(\"report.xlsx\").columns.tolist())\n# ['Unnamed: 0', 'region', 'sales']\n",[22,407,408,423,436],{"__ignoreMap":20},[279,409,410,413,416,419],{"class":220,"line":281},[279,411,412],{"class":314},"df.to_excel(",[279,414,415],{"class":288},"\"report.xlsx\"",[279,417,418],{"class":314},")                     ",[279,420,422],{"class":421},"s-wDw","# index=True is the default\n",[279,424,425,428,431,433],{"class":220,"line":324},[279,426,427],{"class":380},"print",[279,429,430],{"class":314},"(pd.read_excel(",[279,432,415],{"class":288},[279,434,435],{"class":314},").columns.tolist())\n",[279,437,438],{"class":220,"line":338},[279,439,440],{"class":421},"# ['Unnamed: 0', 'region', 'sales']\n",[10,442,443],{},"There are two fixes, and which one you want depends on whether the index meant anything. If it was just row numbers, stop writing it:",[14,445,447],{"className":301,"code":446,"language":303,"meta":20,"style":20},"df.to_excel(\"report.xlsx\", index=False)\nprint(pd.read_excel(\"report.xlsx\").columns.tolist())\n# ['region', 'sales']\n",[22,448,449,469,479],{"__ignoreMap":20},[279,450,451,453,455,457,461,463,466],{"class":220,"line":281},[279,452,412],{"class":314},[279,454,415],{"class":288},[279,456,366],{"class":314},[279,458,460],{"class":459},"sa561","index",[279,462,351],{"class":310},[279,464,465],{"class":380},"False",[279,467,468],{"class":314},")\n",[279,470,471,473,475,477],{"class":220,"line":324},[279,472,427],{"class":380},[279,474,430],{"class":314},[279,476,415],{"class":288},[279,478,435],{"class":314},[279,480,481],{"class":220,"line":338},[279,482,483],{"class":421},"# ['region', 'sales']\n",[10,485,486,487,490],{},"If the index carried real labels — customer IDs, dates, a region key — keep writing it, and tell ",[22,488,489],{},"read_excel"," that column A is the index:",[14,492,494],{"className":301,"code":493,"language":303,"meta":20,"style":20},"labelled = df.set_index(\"region\")\nlabelled.to_excel(\"labelled.xlsx\")\nback = pd.read_excel(\"labelled.xlsx\", index_col=0)\nprint(back.index.name, back.columns.tolist())\n# region ['sales']\n",[22,495,496,510,520,543,550],{"__ignoreMap":20},[279,497,498,501,503,506,508],{"class":220,"line":281},[279,499,500],{"class":314},"labelled ",[279,502,351],{"class":310},[279,504,505],{"class":314}," df.set_index(",[279,507,357],{"class":288},[279,509,468],{"class":314},[279,511,512,515,518],{"class":220,"line":324},[279,513,514],{"class":314},"labelled.to_excel(",[279,516,517],{"class":288},"\"labelled.xlsx\"",[279,519,468],{"class":314},[279,521,522,525,527,530,532,534,537,539,541],{"class":220,"line":338},[279,523,524],{"class":314},"back ",[279,526,351],{"class":310},[279,528,529],{"class":314}," pd.read_excel(",[279,531,517],{"class":288},[279,533,366],{"class":314},[279,535,536],{"class":459},"index_col",[279,538,351],{"class":310},[279,540,78],{"class":380},[279,542,468],{"class":314},[279,544,545,547],{"class":220,"line":345},[279,546,427],{"class":380},[279,548,549],{"class":314},"(back.index.name, back.columns.tolist())\n",[279,551,553],{"class":220,"line":552},5,[279,554,555],{"class":421},"# region ['sales']\n",[10,557,558,559,562,563,565,566,569,570,573,574,577,578,581,582,584,585,588,589,593],{},"Naming the index before writing (",[22,560,561],{},"df.index.name = \"key\"",") has a useful side effect: A1 is no longer empty, so even a reader who forgets ",[22,564,536],{}," gets a column called ",[22,567,568],{},"key"," rather than ",[22,571,572],{},"Unnamed: 0",". The same thing happens with CSV — ",[22,575,576],{},"to_csv"," also writes the index by default, and ",[22,579,580],{},"read_csv"," produces the same ",[22,583,572],{}," — so the habit of passing ",[22,586,587],{},"index=False"," pays off in both formats. ",[50,590,592],{"href":591},"\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-pandas-dataframe-to-excel-without-index\u002F","Write a Pandas DataFrame to Excel Without the Index"," covers the writing side in more detail.",[267,595,597],{"id":596},"cause-2-a-blank-header-above-real-data","Cause 2 — a blank header above real data",[10,599,600],{},"Hand-built sheets often have a column whose heading nobody typed: a notes column, a flag, a second amount column squeezed in next to the first. pandas cannot guess the name, so it numbers it:",[14,602,604],{"className":301,"code":603,"language":303,"meta":20,"style":20},"wb = Workbook()\nws = wb.active\nws.append([\"id\", \"name\", None, \"amount\"])\nws.append([1, \"Ada\", \"rush\", 30])\nws.append([2, \"Ben\", None, 45])\nwb.save(\"orders.xlsx\")\n\norders = pd.read_excel(\"orders.xlsx\")\nprint(orders.columns.tolist())\n# ['id', 'name', 'Unnamed: 2', 'amount']\n",[22,605,606,616,626,652,675,697,708,713,727,735],{"__ignoreMap":20},[279,607,608,611,613],{"class":220,"line":281},[279,609,610],{"class":314},"wb ",[279,612,351],{"class":310},[279,614,615],{"class":314}," Workbook()\n",[279,617,618,621,623],{"class":220,"line":324},[279,619,620],{"class":314},"ws ",[279,622,351],{"class":310},[279,624,625],{"class":314}," wb.active\n",[279,627,628,631,634,636,639,641,644,646,649],{"class":220,"line":338},[279,629,630],{"class":314},"ws.append([",[279,632,633],{"class":288},"\"id\"",[279,635,366],{"class":314},[279,637,638],{"class":288},"\"name\"",[279,640,366],{"class":314},[279,642,643],{"class":380},"None",[279,645,366],{"class":314},[279,647,648],{"class":288},"\"amount\"",[279,650,651],{"class":314},"])\n",[279,653,654,656,658,660,663,665,668,670,673],{"class":220,"line":345},[279,655,630],{"class":314},[279,657,159],{"class":380},[279,659,366],{"class":314},[279,661,662],{"class":288},"\"Ada\"",[279,664,366],{"class":314},[279,666,667],{"class":288},"\"rush\"",[279,669,366],{"class":314},[279,671,672],{"class":380},"30",[279,674,651],{"class":314},[279,676,677,679,681,683,686,688,690,692,695],{"class":220,"line":552},[279,678,630],{"class":314},[279,680,181],{"class":380},[279,682,366],{"class":314},[279,684,685],{"class":288},"\"Ben\"",[279,687,366],{"class":314},[279,689,643],{"class":380},[279,691,366],{"class":314},[279,693,694],{"class":380},"45",[279,696,651],{"class":314},[279,698,700,703,706],{"class":220,"line":699},6,[279,701,702],{"class":314},"wb.save(",[279,704,705],{"class":288},"\"orders.xlsx\"",[279,707,468],{"class":314},[279,709,711],{"class":220,"line":710},7,[279,712,342],{"emptyLinePlaceholder":341},[279,714,716,719,721,723,725],{"class":220,"line":715},8,[279,717,718],{"class":314},"orders ",[279,720,351],{"class":310},[279,722,529],{"class":314},[279,724,705],{"class":288},[279,726,468],{"class":314},[279,728,730,732],{"class":220,"line":729},9,[279,731,427],{"class":380},[279,733,734],{"class":314},"(orders.columns.tolist())\n",[279,736,738],{"class":220,"line":737},10,[279,739,740],{"class":421},"# ['id', 'name', 'Unnamed: 2', 'amount']\n",[10,742,743,744,747,748,751],{},"Column C holds data, so dropping it would lose the \"rush\" flag. Rename it instead. Because the generated name depends on the column's ",[45,745,746],{},"position",", rename by position rather than by the ",[22,749,750],{},"Unnamed: 2"," string — if someone inserts a column to the left next month, the number changes and a name-based rename silently stops matching:",[14,753,755],{"className":301,"code":754,"language":303,"meta":20,"style":20},"cols = list(orders.columns)\ncols[2] = \"flag\"\norders.columns = cols\nprint(orders.columns.tolist())\n# ['id', 'name', 'flag', 'amount']\n",[22,756,757,770,785,795,801],{"__ignoreMap":20},[279,758,759,762,764,767],{"class":220,"line":281},[279,760,761],{"class":314},"cols ",[279,763,351],{"class":310},[279,765,766],{"class":380}," list",[279,768,769],{"class":314},"(orders.columns)\n",[279,771,772,775,777,780,782],{"class":220,"line":324},[279,773,774],{"class":314},"cols[",[279,776,181],{"class":380},[279,778,779],{"class":314},"] ",[279,781,351],{"class":310},[279,783,784],{"class":288}," \"flag\"\n",[279,786,787,790,792],{"class":220,"line":338},[279,788,789],{"class":314},"orders.columns ",[279,791,351],{"class":310},[279,793,794],{"class":314}," cols\n",[279,796,797,799],{"class":220,"line":345},[279,798,427],{"class":380},[279,800,734],{"class":314},[279,802,803],{"class":220,"line":552},[279,804,805],{"class":421},"# ['id', 'name', 'flag', 'amount']\n",[10,807,808,809,812,813,816],{},"When the layout is fixed and agreed, the cleanest option is to ignore the file's header row altogether and supply your own names. ",[22,810,811],{},"header=0"," says row 1 is a header (so it is skipped), and ",[22,814,815],{},"names="," replaces it:",[14,818,820],{"className":301,"code":819,"language":303,"meta":20,"style":20},"orders = pd.read_excel(\"orders.xlsx\", header=0, names=[\"id\", \"name\", \"flag\", \"amount\"])\nprint(orders.columns.tolist())\n",[22,821,822,868],{"__ignoreMap":20},[279,823,824,826,828,830,832,834,837,839,841,843,846,848,851,853,855,857,859,862,864,866],{"class":220,"line":281},[279,825,718],{"class":314},[279,827,351],{"class":310},[279,829,529],{"class":314},[279,831,705],{"class":288},[279,833,366],{"class":314},[279,835,836],{"class":459},"header",[279,838,351],{"class":310},[279,840,78],{"class":380},[279,842,366],{"class":314},[279,844,845],{"class":459},"names",[279,847,351],{"class":310},[279,849,850],{"class":314},"[",[279,852,633],{"class":288},[279,854,366],{"class":314},[279,856,638],{"class":288},[279,858,366],{"class":314},[279,860,861],{"class":288},"\"flag\"",[279,863,366],{"class":314},[279,865,648],{"class":288},[279,867,651],{"class":314},[279,869,870,872],{"class":220,"line":324},[279,871,427],{"class":380},[279,873,734],{"class":314},[10,875,876,878,879,882],{},[22,877,815],{}," must list exactly as many names as the columns being read. If the sheet may grow extra columns on the right, combine it with ",[22,880,881],{},"usecols=\"A:D\""," so the count stays fixed.",[56,884,65,890,65,893,65,896,65,901,65,908,65,915,65,919,65,923,65,927,65,930,65,933,65,941,65,946,65,951,65,957,65,961,65,965,65,969,65,972,65,975,65,979,65,982,65,986,65,992,65,996,65,999,65,1002,65,1005,65,1008,65,1012,65,1015,65,1020,65,1027,65,1032,65,1036,65,1040,65,1044,65,1046,65,1049,65,1053,65,1056,65,1059,65,1065,65,1068,65,1071,65,1074],{"viewBox":885,"role":59,"ariaLabelledBy":886,"xmlns":63,"style":889},"4 0 752 308",[887,888],"unn-cause-t","unn-cause-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[67,891,892],{"id":887},"Choosing the fix for an Unnamed column",[71,894,895],{"id":888},"A decision chart. If the Unnamed column is column A and holds 0, 1, 2 it is a saved index: use index_col=0 or write with index=False. If it holds real values under a blank heading, rename it by position or pass names. If it is entirely empty, restrict usecols or drop all-empty columns. If the name ends in _level_1, it comes from a multi-row header and should be flattened.",[75,897],{"x":898,"y":78,"width":899,"height":900,"fill":81},"4","752","308",[75,902],{"x":903,"y":904,"width":905,"height":906,"rx":238,"fill":907,"stroke":225,"style":226},"236.7","16.0","286.7","75.5","#f0f4ff",[104,909,911],{"transform":910},"translate(368.0,29.0) scale(1.000)",[108,912],{"d":913,"fill":111,"stroke":914,"style":246},"M11 4a7 7 0 1 0 .01 0z M16 16l5 5","var(--brand-strong,#4338ca)",[19,916,918],{"x":84,"y":906,"style":917},"font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","What is in the Unnamed column?",[220,920],{"x1":84,"y1":921,"x2":84,"y2":922,"stroke":225,"style":226},"91.5","111.5",[220,924],{"x1":925,"y1":922,"x2":926,"y2":922,"stroke":225,"style":226},"104.0","656.0",[220,928],{"x1":925,"y1":922,"x2":925,"y2":929,"stroke":225,"style":226},"157.5",[228,931],{"points":932,"fill":231},"104.0,161.5 99.0,152.5 109.0,152.5",[75,934],{"x":935,"y":936,"width":937,"height":938,"rx":939,"fill":81,"stroke":96,"style":940},"34.0","121.5","139.9","21.0","10","stroke-width:1.2px",[19,942,945],{"x":925,"y":943,"style":944},"136.0","font-size:11.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","0, 1, 2 … in column A",[75,947],{"x":948,"y":949,"width":950,"height":237,"rx":238,"fill":907,"stroke":225,"style":226},"20.0","163.5","168.0",[104,952,954],{"transform":953},"translate(92.0,185.2) scale(1.000)",[108,955],{"d":956,"fill":111,"stroke":914,"style":246},"M3 5h18v14H3z M3 10h18 M3 15h18 M9 5v14",[19,958,960],{"x":925,"y":959,"style":917},"231.8","A saved index",[19,962,964],{"x":925,"y":963,"style":256},"251.2","index_col=0, or write",[19,966,968],{"x":925,"y":967,"style":256},"268.8","with index=False",[220,970],{"x1":971,"y1":922,"x2":971,"y2":929,"stroke":225,"style":226},"288.0",[228,973],{"points":974,"fill":231},"288.0,161.5 283.0,152.5 293.0,152.5",[75,976],{"x":977,"y":936,"width":978,"height":938,"rx":939,"fill":81,"stroke":96,"style":940},"246.9","82.3",[19,980,981],{"x":971,"y":943,"style":944},"real values",[75,983],{"x":116,"y":949,"width":950,"height":237,"rx":238,"fill":984,"stroke":985,"style":226},"#d9f4f1","var(--teal,#0f9488)",[104,987,989],{"transform":988},"translate(276.0,185.2) scale(1.000)",[108,990],{"d":991,"fill":111,"stroke":112,"style":246},"M4 4h16v16H4z M4 9h16 M4 14h16 M10 4v16",[19,993,995],{"x":971,"y":959,"style":994},"font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","A blank heading",[19,997,998],{"x":971,"y":963,"style":256},"rename by position, or",[19,1000,1001],{"x":971,"y":967,"style":256},"pass names=",[220,1003],{"x1":1004,"y1":922,"x2":1004,"y2":929,"stroke":225,"style":226},"472.0",[228,1006],{"points":1007,"fill":231},"472.0,161.5 467.0,152.5 477.0,152.5",[75,1009],{"x":1010,"y":936,"width":1011,"height":938,"rx":939,"fill":81,"stroke":96,"style":940},"425.0","94.0",[19,1013,1014],{"x":1004,"y":943,"style":944},"nothing at all",[75,1016],{"x":1017,"y":949,"width":950,"height":237,"rx":238,"fill":1018,"stroke":1019,"style":226},"388.0","#fdefd8","var(--gold,#b4740a)",[104,1021,1023],{"transform":1022},"translate(460.0,176.5) scale(1.000)",[108,1024],{"d":1025,"fill":111,"stroke":1026,"style":246},"M3 5h18l-7 8v6l-4 2v-8z","var(--gold-ink,#7a4e06)",[19,1028,1031],{"x":1004,"y":1029,"style":1030},"223.0","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Formatted empty",[19,1033,1035],{"x":1004,"y":1034,"style":1030},"240.5","cells",[19,1037,1039],{"x":1004,"y":1038,"style":256},"260.0","usecols, or drop",[19,1041,1043],{"x":1004,"y":1042,"style":256},"277.5","all-empty columns",[220,1045],{"x1":926,"y1":922,"x2":926,"y2":929,"stroke":225,"style":226},[228,1047],{"points":1048,"fill":231},"656.0,161.5 651.0,152.5 661.0,152.5",[75,1050],{"x":1051,"y":936,"width":1052,"height":938,"rx":939,"fill":81,"stroke":96,"style":940},"590.8","130.5",[19,1054,1055],{"x":926,"y":943,"style":944},"name ends _level_1",[75,1057],{"x":1058,"y":949,"width":950,"height":237,"rx":238,"fill":162,"stroke":163,"style":226},"572.0",[104,1060,1062],{"transform":1061},"translate(644.0,176.5) scale(1.000)",[108,1063],{"d":1064,"fill":111,"stroke":245,"style":246},"M12 3l9 5-9 5-9-5z M3 13l9 5 9-5 M3 17l9 5 9-5",[19,1066,1067],{"x":926,"y":1029,"style":251},"Multi-row header",[19,1069,1070],{"x":926,"y":1034,"style":251},"gap",[19,1072,1073],{"x":926,"y":1038,"style":256},"flatten or rename the",[19,1075,1076],{"x":926,"y":1042,"style":256},"tuples",[267,1078,1080],{"id":1079},"cause-3-empty-columns-that-excel-thinks-are-in-use","Cause 3 — empty columns that Excel thinks are in use",[10,1082,1083,1084,366,1087,366,1090,1093],{},"The trailing ",[22,1085,1086],{},"Unnamed: 4",[22,1088,1089],{},"Unnamed: 5",[22,1091,1092],{},"Unnamed: 6"," in the second example at the top are a different animal. Those columns are empty, but something in them — a fill colour, a border, a single space somebody typed and deleted the rest of — made Excel record them as part of the sheet's used range. openpyxl reports that range faithfully and pandas reads every column in it.",[14,1095,1097],{"className":301,"code":1096,"language":303,"meta":20,"style":20},"wb = Workbook()\nws = wb.active\nws.append([\"id\", \"amount\"])\nws.append([1, 30])\nws.append([2, 45])\nfrom openpyxl.styles import PatternFill\nws[\"D3\"].fill = PatternFill(\"solid\", fgColor=\"FFFF00\")   # formatting only\nws[\"E2\"] = \" \"                                             # a stray space\nwb.save(\"wide.xlsx\")\n\nwide = pd.read_excel(\"wide.xlsx\")\nprint(wide.columns.tolist())\n# ['id', 'amount', 'Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4']\n",[22,1098,1099,1107,1115,1127,1139,1151,1163,1198,1215,1224,1228,1242,1250],{"__ignoreMap":20},[279,1100,1101,1103,1105],{"class":220,"line":281},[279,1102,610],{"class":314},[279,1104,351],{"class":310},[279,1106,615],{"class":314},[279,1108,1109,1111,1113],{"class":220,"line":324},[279,1110,620],{"class":314},[279,1112,351],{"class":310},[279,1114,625],{"class":314},[279,1116,1117,1119,1121,1123,1125],{"class":220,"line":338},[279,1118,630],{"class":314},[279,1120,633],{"class":288},[279,1122,366],{"class":314},[279,1124,648],{"class":288},[279,1126,651],{"class":314},[279,1128,1129,1131,1133,1135,1137],{"class":220,"line":345},[279,1130,630],{"class":314},[279,1132,159],{"class":380},[279,1134,366],{"class":314},[279,1136,672],{"class":380},[279,1138,651],{"class":314},[279,1140,1141,1143,1145,1147,1149],{"class":220,"line":552},[279,1142,630],{"class":314},[279,1144,181],{"class":380},[279,1146,366],{"class":314},[279,1148,694],{"class":380},[279,1150,651],{"class":314},[279,1152,1153,1155,1158,1160],{"class":220,"line":699},[279,1154,327],{"class":310},[279,1156,1157],{"class":314}," openpyxl.styles ",[279,1159,311],{"class":310},[279,1161,1162],{"class":314}," PatternFill\n",[279,1164,1165,1168,1171,1174,1176,1179,1182,1184,1187,1189,1192,1195],{"class":220,"line":710},[279,1166,1167],{"class":314},"ws[",[279,1169,1170],{"class":288},"\"D3\"",[279,1172,1173],{"class":314},"].fill ",[279,1175,351],{"class":310},[279,1177,1178],{"class":314}," PatternFill(",[279,1180,1181],{"class":288},"\"solid\"",[279,1183,366],{"class":314},[279,1185,1186],{"class":459},"fgColor",[279,1188,351],{"class":310},[279,1190,1191],{"class":288},"\"FFFF00\"",[279,1193,1194],{"class":314},")   ",[279,1196,1197],{"class":421},"# formatting only\n",[279,1199,1200,1202,1205,1207,1209,1212],{"class":220,"line":715},[279,1201,1167],{"class":314},[279,1203,1204],{"class":288},"\"E2\"",[279,1206,779],{"class":314},[279,1208,351],{"class":310},[279,1210,1211],{"class":288}," \" \"",[279,1213,1214],{"class":421},"                                             # a stray space\n",[279,1216,1217,1219,1222],{"class":220,"line":729},[279,1218,702],{"class":314},[279,1220,1221],{"class":288},"\"wide.xlsx\"",[279,1223,468],{"class":314},[279,1225,1226],{"class":220,"line":737},[279,1227,342],{"emptyLinePlaceholder":341},[279,1229,1231,1234,1236,1238,1240],{"class":220,"line":1230},11,[279,1232,1233],{"class":314},"wide ",[279,1235,351],{"class":310},[279,1237,529],{"class":314},[279,1239,1221],{"class":288},[279,1241,468],{"class":314},[279,1243,1245,1247],{"class":220,"line":1244},12,[279,1246,427],{"class":380},[279,1248,1249],{"class":314},"(wide.columns.tolist())\n",[279,1251,1253],{"class":220,"line":1252},13,[279,1254,1255],{"class":421},"# ['id', 'amount', 'Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4']\n",[10,1257,1258,1259,1262],{},"The quickest fix, when you know which columns matter, is not to read the others at all. ",[22,1260,1261],{},"usecols"," accepts a letter range, a list of names, or a function that receives each header and returns whether to keep it:",[14,1264,1266],{"className":301,"code":1265,"language":303,"meta":20,"style":20},"print(pd.read_excel(\"wide.xlsx\", usecols=\"A:B\").columns.tolist())\nkeep = pd.read_excel(\"wide.xlsx\", usecols=lambda c: not str(c).startswith(\"Unnamed\"))\nprint(keep.columns.tolist())\n# ['id', 'amount']\n",[22,1267,1268,1287,1323,1330],{"__ignoreMap":20},[279,1269,1270,1272,1274,1276,1278,1280,1282,1285],{"class":220,"line":281},[279,1271,427],{"class":380},[279,1273,430],{"class":314},[279,1275,1221],{"class":288},[279,1277,366],{"class":314},[279,1279,1261],{"class":459},[279,1281,351],{"class":310},[279,1283,1284],{"class":288},"\"A:B\"",[279,1286,435],{"class":314},[279,1288,1289,1292,1294,1296,1298,1300,1302,1305,1308,1311,1314,1317,1320],{"class":220,"line":324},[279,1290,1291],{"class":314},"keep ",[279,1293,351],{"class":310},[279,1295,529],{"class":314},[279,1297,1221],{"class":288},[279,1299,366],{"class":314},[279,1301,1261],{"class":459},[279,1303,1304],{"class":310},"=lambda",[279,1306,1307],{"class":314}," c: ",[279,1309,1310],{"class":310},"not",[279,1312,1313],{"class":380}," str",[279,1315,1316],{"class":314},"(c).startswith(",[279,1318,1319],{"class":288},"\"Unnamed\"",[279,1321,1322],{"class":314},"))\n",[279,1324,1325,1327],{"class":220,"line":338},[279,1326,427],{"class":380},[279,1328,1329],{"class":314},"(keep.columns.tolist())\n",[279,1331,1332],{"class":220,"line":345},[279,1333,1334],{"class":421},"# ['id', 'amount']\n",[10,1336,1337,1338,1341],{},"The callable version is convenient but has the same danger as dropping by name: it also discards a real column with a blank heading. When the sheet can contain both kinds, drop only the columns that are genuinely empty. That needs one extra step, because ",[22,1339,1340],{},"dropna(axis=1, how=\"all\")"," does not treat the stray space as missing:",[14,1343,1345],{"className":301,"code":1344,"language":303,"meta":20,"style":20},"print(wide.dropna(axis=1, how=\"all\").columns.tolist())\n# ['id', 'amount', 'Unnamed: 4']   \u003C- the column with \" \" survives\n\ntext = wide.select_dtypes(include=[\"object\", \"string\"]).columns\nwide[text] = wide[text].apply(lambda s: s.str.strip().replace(\"\", pd.NA))\nprint(wide.dropna(axis=1, how=\"all\").columns.tolist())\n# ['id', 'amount']\n",[22,1346,1347,1373,1378,1382,1410,1437,1459],{"__ignoreMap":20},[279,1348,1349,1351,1354,1357,1359,1361,1363,1366,1368,1371],{"class":220,"line":281},[279,1350,427],{"class":380},[279,1352,1353],{"class":314},"(wide.dropna(",[279,1355,1356],{"class":459},"axis",[279,1358,351],{"class":310},[279,1360,159],{"class":380},[279,1362,366],{"class":314},[279,1364,1365],{"class":459},"how",[279,1367,351],{"class":310},[279,1369,1370],{"class":288},"\"all\"",[279,1372,435],{"class":314},[279,1374,1375],{"class":220,"line":324},[279,1376,1377],{"class":421},"# ['id', 'amount', 'Unnamed: 4']   \u003C- the column with \" \" survives\n",[279,1379,1380],{"class":220,"line":338},[279,1381,342],{"emptyLinePlaceholder":341},[279,1383,1384,1387,1389,1392,1395,1397,1399,1402,1404,1407],{"class":220,"line":345},[279,1385,1386],{"class":314},"text ",[279,1388,351],{"class":310},[279,1390,1391],{"class":314}," wide.select_dtypes(",[279,1393,1394],{"class":459},"include",[279,1396,351],{"class":310},[279,1398,850],{"class":314},[279,1400,1401],{"class":288},"\"object\"",[279,1403,366],{"class":314},[279,1405,1406],{"class":288},"\"string\"",[279,1408,1409],{"class":314},"]).columns\n",[279,1411,1412,1415,1417,1420,1423,1426,1429,1432,1435],{"class":220,"line":552},[279,1413,1414],{"class":314},"wide[text] ",[279,1416,351],{"class":310},[279,1418,1419],{"class":314}," wide[text].apply(",[279,1421,1422],{"class":310},"lambda",[279,1424,1425],{"class":314}," s: s.str.strip().replace(",[279,1427,1428],{"class":288},"\"\"",[279,1430,1431],{"class":314},", pd.",[279,1433,1434],{"class":380},"NA",[279,1436,1322],{"class":314},[279,1438,1439,1441,1443,1445,1447,1449,1451,1453,1455,1457],{"class":220,"line":699},[279,1440,427],{"class":380},[279,1442,1353],{"class":314},[279,1444,1356],{"class":459},[279,1446,351],{"class":310},[279,1448,159],{"class":380},[279,1450,366],{"class":314},[279,1452,1365],{"class":459},[279,1454,351],{"class":310},[279,1456,1370],{"class":288},[279,1458,435],{"class":314},[279,1460,1461],{"class":220,"line":710},[279,1462,1334],{"class":421},[10,1464,1465,1466,1470],{},"If the same workbook comes back every week, it is also worth fixing at the source: select the stray columns in Excel, clear them (Home → Clear → Clear All), and save. The used range shrinks and the phantom columns disappear for every reader, not just your script. ",[50,1467,1469],{"href":1468},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-max-row-counting-empty-rows\u002F","Fix openpyxl max_row Counting Empty Rows"," explains the same used-range effect for rows.",[267,1472,1474],{"id":1473},"cause-4-gaps-in-a-multi-row-header","Cause 4 — gaps in a multi-row header",[10,1476,1477,1478,1481,1482,1485],{},"Reports with grouped headings — \"Sales\" spanning Q1 and Q2, \"Region\" sitting above a blank — read with ",[22,1479,1480],{},"header=[0, 1]"," produce a MultiIndex, and every blank in the second header row gets a generated name with a ",[22,1483,1484],{},"_level_1"," suffix:",[14,1487,1489],{"className":301,"code":1488,"language":303,"meta":20,"style":20},"wb = Workbook()\nws = wb.active\nws.append([\"Region\", None, \"Sales\", None])\nws.append([None, \"Code\", \"Q1\", \"Q2\"])\nws.append([\"North\", \"N1\", 410, 380])\nws.merge_cells(\"A1:B1\")\nws.merge_cells(\"C1:D1\")\nwb.save(\"grouped.xlsx\")\n\ngrouped = pd.read_excel(\"grouped.xlsx\", header=[0, 1])\nprint(grouped.columns.tolist())\n# [('Region', 'Unnamed: 0_level_1'), ('Region', 'Code'), ('Sales', 'Q1'), ('Sales', 'Q2')]\n",[22,1490,1491,1499,1507,1529,1552,1574,1584,1593,1602,1606,1633,1640],{"__ignoreMap":20},[279,1492,1493,1495,1497],{"class":220,"line":281},[279,1494,610],{"class":314},[279,1496,351],{"class":310},[279,1498,615],{"class":314},[279,1500,1501,1503,1505],{"class":220,"line":324},[279,1502,620],{"class":314},[279,1504,351],{"class":310},[279,1506,625],{"class":314},[279,1508,1509,1511,1514,1516,1518,1520,1523,1525,1527],{"class":220,"line":338},[279,1510,630],{"class":314},[279,1512,1513],{"class":288},"\"Region\"",[279,1515,366],{"class":314},[279,1517,643],{"class":380},[279,1519,366],{"class":314},[279,1521,1522],{"class":288},"\"Sales\"",[279,1524,366],{"class":314},[279,1526,643],{"class":380},[279,1528,651],{"class":314},[279,1530,1531,1533,1535,1537,1540,1542,1545,1547,1550],{"class":220,"line":345},[279,1532,630],{"class":314},[279,1534,643],{"class":380},[279,1536,366],{"class":314},[279,1538,1539],{"class":288},"\"Code\"",[279,1541,366],{"class":314},[279,1543,1544],{"class":288},"\"Q1\"",[279,1546,366],{"class":314},[279,1548,1549],{"class":288},"\"Q2\"",[279,1551,651],{"class":314},[279,1553,1554,1556,1558,1560,1563,1565,1567,1569,1572],{"class":220,"line":552},[279,1555,630],{"class":314},[279,1557,363],{"class":288},[279,1559,366],{"class":314},[279,1561,1562],{"class":288},"\"N1\"",[279,1564,366],{"class":314},[279,1566,197],{"class":380},[279,1568,366],{"class":314},[279,1570,1571],{"class":380},"380",[279,1573,651],{"class":314},[279,1575,1576,1579,1582],{"class":220,"line":699},[279,1577,1578],{"class":314},"ws.merge_cells(",[279,1580,1581],{"class":288},"\"A1:B1\"",[279,1583,468],{"class":314},[279,1585,1586,1588,1591],{"class":220,"line":710},[279,1587,1578],{"class":314},[279,1589,1590],{"class":288},"\"C1:D1\"",[279,1592,468],{"class":314},[279,1594,1595,1597,1600],{"class":220,"line":715},[279,1596,702],{"class":314},[279,1598,1599],{"class":288},"\"grouped.xlsx\"",[279,1601,468],{"class":314},[279,1603,1604],{"class":220,"line":729},[279,1605,342],{"emptyLinePlaceholder":341},[279,1607,1608,1611,1613,1615,1617,1619,1621,1623,1625,1627,1629,1631],{"class":220,"line":737},[279,1609,1610],{"class":314},"grouped ",[279,1612,351],{"class":310},[279,1614,529],{"class":314},[279,1616,1599],{"class":288},[279,1618,366],{"class":314},[279,1620,836],{"class":459},[279,1622,351],{"class":310},[279,1624,850],{"class":314},[279,1626,78],{"class":380},[279,1628,366],{"class":314},[279,1630,159],{"class":380},[279,1632,651],{"class":314},[279,1634,1635,1637],{"class":220,"line":1230},[279,1636,427],{"class":380},[279,1638,1639],{"class":314},"(grouped.columns.tolist())\n",[279,1641,1642],{"class":220,"line":1244},[279,1643,1644],{"class":421},"# [('Region', 'Unnamed: 0_level_1'), ('Region', 'Code'), ('Sales', 'Q1'), ('Sales', 'Q2')]\n",[10,1646,1647],{},"Flatten the two levels into one string per column and drop the generated part as you go:",[14,1649,1651],{"className":301,"code":1650,"language":303,"meta":20,"style":20},"def flat(col):\n    parts = [str(p) for p in col if not str(p).startswith(\"Unnamed\")]\n    return \" \".join(parts)\n\ngrouped.columns = [flat(c) for c in grouped.columns]\nprint(grouped.columns.tolist())\n# ['Region', 'Region Code', 'Sales Q1', 'Sales Q2']\n",[22,1652,1653,1665,1709,1719,1723,1743,1749],{"__ignoreMap":20},[279,1654,1655,1658,1662],{"class":220,"line":281},[279,1656,1657],{"class":310},"def",[279,1659,1661],{"class":1660},"s_Opv"," flat",[279,1663,1664],{"class":314},"(col):\n",[279,1666,1667,1670,1672,1675,1678,1681,1684,1687,1690,1693,1696,1699,1701,1704,1706],{"class":220,"line":324},[279,1668,1669],{"class":314},"    parts ",[279,1671,351],{"class":310},[279,1673,1674],{"class":314}," [",[279,1676,1677],{"class":380},"str",[279,1679,1680],{"class":314},"(p) ",[279,1682,1683],{"class":310},"for",[279,1685,1686],{"class":314}," p ",[279,1688,1689],{"class":310},"in",[279,1691,1692],{"class":314}," col ",[279,1694,1695],{"class":310},"if",[279,1697,1698],{"class":310}," not",[279,1700,1313],{"class":380},[279,1702,1703],{"class":314},"(p).startswith(",[279,1705,1319],{"class":288},[279,1707,1708],{"class":314},")]\n",[279,1710,1711,1714,1716],{"class":220,"line":338},[279,1712,1713],{"class":310},"    return",[279,1715,1211],{"class":288},[279,1717,1718],{"class":314},".join(parts)\n",[279,1720,1721],{"class":220,"line":345},[279,1722,342],{"emptyLinePlaceholder":341},[279,1724,1725,1728,1730,1733,1735,1738,1740],{"class":220,"line":552},[279,1726,1727],{"class":314},"grouped.columns ",[279,1729,351],{"class":310},[279,1731,1732],{"class":314}," [flat(c) ",[279,1734,1683],{"class":310},[279,1736,1737],{"class":314}," c ",[279,1739,1689],{"class":310},[279,1741,1742],{"class":314}," grouped.columns]\n",[279,1744,1745,1747],{"class":220,"line":699},[279,1746,427],{"class":380},[279,1748,1639],{"class":314},[279,1750,1751],{"class":220,"line":710},[279,1752,1753],{"class":421},"# ['Region', 'Region Code', 'Sales Q1', 'Sales Q2']\n",[10,1755,1756,1757,1761],{},"The full technique, including headers that span three rows, is in ",[50,1758,1760],{"href":1759},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets\u002Fread-excel-with-multi-row-headers-in-pandas\u002F","Read Excel with Multi-Row Headers in pandas",".",[56,1763,65,1768,65,1771,65,1774,65,1777,65,1781,65,1785,65,1791,65,1794,65,1798,65,1801,65,1805,65,1808,65,1812,65,1815,65,1819,65,1821,65,1828,65,1830,65,1836,65,1838,65,1843,65,1845,65,1850,65,1853,65,1857,65,1859,65,1865,65,1867,65,1872,65,1874,65,1879,65,1881,65,1886,65,1889,65,1893,65,1895,65,1900,65,1902,65,1907,65,1909,65,1914,65,1916,65,1921,65,1923,65,1927,65,1929,65,1934,65,1936,65,1941,65,1943,65,1948,65,1950],{"viewBox":1764,"role":59,"ariaLabelledBy":1765,"xmlns":63,"style":889},"4 0 752 208",[1766,1767],"unn-fixes-t","unn-fixes-d",[67,1769,1770],{"id":1766},"Which fix is safe for each cause",[71,1772,1773],{"id":1767},"A grid comparing four fixes against four causes. index_col=0 fits only a saved index. Renaming by position fits blank headings and multi-row gaps. usecols fits formatted empty columns and a saved index, but can drop real data under blank headings. Dropping all-empty columns after stripping text fits formatted empty columns only.",[75,1775],{"x":898,"y":78,"width":899,"height":1776,"fill":81},"208",[75,1778],{"x":948,"y":904,"width":1779,"height":1780,"rx":78,"fill":81,"stroke":96,"style":125},"219.3","40.0",[75,1782],{"x":1783,"y":904,"width":1784,"height":1780,"rx":78,"fill":907,"stroke":225,"style":940},"239.3","125.2",[19,1786,1790],{"x":1787,"y":1788,"style":1789},"301.9","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Saved index",[75,1792],{"x":1793,"y":904,"width":1784,"height":1780,"rx":78,"fill":907,"stroke":225,"style":940},"364.5",[19,1795,1797],{"x":1796,"y":1788,"style":1789},"427.1","Blank heading",[75,1799],{"x":1800,"y":904,"width":1784,"height":1780,"rx":78,"fill":907,"stroke":225,"style":940},"489.6",[19,1802,1804],{"x":1803,"y":1788,"style":1789},"552.2","Empty columns",[75,1806],{"x":1807,"y":904,"width":1784,"height":1780,"rx":78,"fill":907,"stroke":225,"style":940},"614.8",[19,1809,1811],{"x":1810,"y":1788,"style":1789},"677.4","Multi-row gap",[75,1813],{"x":948,"y":1814,"width":1779,"height":935,"rx":78,"fill":95,"stroke":96,"style":125},"56.0",[19,1816,1818],{"x":123,"y":122,"style":1817},"font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start","index_col=0 \u002F index=False",[75,1820],{"x":1783,"y":1814,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1822,1824],{"transform":1823},"translate(292.9,64.0) scale(0.750)",[108,1825],{"d":1826,"fill":111,"stroke":985,"style":1827},"M5 12.5l4.5 4.5L19 7","stroke-width:2.40px;stroke-linecap:round;stroke-linejoin:round",[75,1829],{"x":1793,"y":1814,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1831,1833],{"transform":1832},"translate(419.1,65.0) scale(0.667)",[108,1834],{"d":1835,"fill":111,"stroke":163,"style":113},"M6 6l12 12 M18 6L6 18",[75,1837],{"x":1800,"y":1814,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1839,1841],{"transform":1840},"translate(544.2,65.0) scale(0.667)",[108,1842],{"d":1835,"fill":111,"stroke":163,"style":113},[75,1844],{"x":1807,"y":1814,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1846,1848],{"transform":1847},"translate(669.4,65.0) scale(0.667)",[108,1849],{"d":1835,"fill":111,"stroke":163,"style":113},[75,1851],{"x":948,"y":1852,"width":1779,"height":935,"rx":78,"fill":95,"stroke":96,"style":125},"90.0",[19,1854,1856],{"x":123,"y":1855,"style":1817},"112.0","Rename by position \u002F names=",[75,1858],{"x":1783,"y":1852,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1860,1862],{"transform":1861},"translate(293.4,98.5) scale(0.708)",[108,1863],{"d":244,"fill":111,"stroke":1019,"style":1864},"stroke-width:2.54px;stroke-linecap:round;stroke-linejoin:round",[75,1866],{"x":1793,"y":1852,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1868,1870],{"transform":1869},"translate(418.1,98.0) scale(0.750)",[108,1871],{"d":1826,"fill":111,"stroke":985,"style":1827},[75,1873],{"x":1800,"y":1852,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1875,1877],{"transform":1876},"translate(544.2,99.0) scale(0.667)",[108,1878],{"d":1835,"fill":111,"stroke":163,"style":113},[75,1880],{"x":1807,"y":1852,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1882,1884],{"transform":1883},"translate(668.4,98.0) scale(0.750)",[108,1885],{"d":1826,"fill":111,"stroke":985,"style":1827},[75,1887],{"x":948,"y":1888,"width":1779,"height":935,"rx":78,"fill":95,"stroke":96,"style":125},"124.0",[19,1890,1892],{"x":123,"y":1891,"style":1817},"146.0","usecols=…",[75,1894],{"x":1783,"y":1888,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1896,1898],{"transform":1897},"translate(292.9,132.0) scale(0.750)",[108,1899],{"d":1826,"fill":111,"stroke":985,"style":1827},[75,1901],{"x":1793,"y":1888,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1903,1905],{"transform":1904},"translate(418.6,132.5) scale(0.708)",[108,1906],{"d":244,"fill":111,"stroke":1019,"style":1864},[75,1908],{"x":1800,"y":1888,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1910,1912],{"transform":1911},"translate(543.2,132.0) scale(0.750)",[108,1913],{"d":1826,"fill":111,"stroke":985,"style":1827},[75,1915],{"x":1807,"y":1888,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1917,1919],{"transform":1918},"translate(669.4,133.0) scale(0.667)",[108,1920],{"d":1835,"fill":111,"stroke":163,"style":113},[75,1922],{"x":948,"y":200,"width":1779,"height":935,"rx":78,"fill":95,"stroke":96,"style":125},[19,1924,1926],{"x":123,"y":1925,"style":1817},"180.0","Strip, then dropna(how=\"all\")",[75,1928],{"x":1783,"y":200,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1930,1932],{"transform":1931},"translate(293.9,167.0) scale(0.667)",[108,1933],{"d":1835,"fill":111,"stroke":163,"style":113},[75,1935],{"x":1793,"y":200,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1937,1939],{"transform":1938},"translate(419.1,167.0) scale(0.667)",[108,1940],{"d":1835,"fill":111,"stroke":163,"style":113},[75,1942],{"x":1800,"y":200,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1944,1946],{"transform":1945},"translate(543.2,166.0) scale(0.750)",[108,1947],{"d":1826,"fill":111,"stroke":985,"style":1827},[75,1949],{"x":1807,"y":200,"width":1784,"height":935,"rx":78,"fill":81,"stroke":96,"style":125},[104,1951,1953],{"transform":1952},"translate(669.4,167.0) scale(0.667)",[108,1954],{"d":1835,"fill":111,"stroke":163,"style":113},[267,1956,1958],{"id":1957},"make-the-fix-permanent-in-a-reading-function","Make the fix permanent in a reading function",[10,1960,1961],{},"When a script reads the same kind of file repeatedly, wrap the rules in one function so every caller gets the same, checked result. This one keeps real data, removes the phantoms, and fails loudly if a required column is missing:",[14,1963,1965],{"className":301,"code":1964,"language":303,"meta":20,"style":20},"REQUIRED = {\"id\", \"amount\"}\n\ndef read_clean(path, **kwargs):\n    frame = pd.read_excel(path, **kwargs)\n    text = frame.select_dtypes(include=[\"object\", \"string\"]).columns\n    frame[text] = frame[text].apply(lambda s: s.str.strip().replace(\"\", pd.NA))\n    frame = frame.dropna(axis=1, how=\"all\")\n    leftover = [c for c in frame.columns if str(c).startswith(\"Unnamed\")]\n    if leftover:\n        raise ValueError(f\"unnamed columns hold data: {leftover} — name them in the sheet or pass names=\")\n    missing = REQUIRED - set(frame.columns)\n    if missing:\n        raise ValueError(f\"missing columns: {sorted(missing)}\")\n    return frame\n\nprint(read_clean(\"wide.xlsx\").columns.tolist())\n# ['id', 'amount']\n",[22,1966,1967,1987,1991,2007,2022,2046,2068,2093,2122,2130,2162,2181,2188,2216,2224,2229,2241],{"__ignoreMap":20},[279,1968,1969,1972,1975,1978,1980,1982,1984],{"class":220,"line":281},[279,1970,1971],{"class":380},"REQUIRED",[279,1973,1974],{"class":310}," =",[279,1976,1977],{"class":314}," {",[279,1979,633],{"class":288},[279,1981,366],{"class":314},[279,1983,648],{"class":288},[279,1985,1986],{"class":314},"}\n",[279,1988,1989],{"class":220,"line":324},[279,1990,342],{"emptyLinePlaceholder":341},[279,1992,1993,1995,1998,2001,2004],{"class":220,"line":338},[279,1994,1657],{"class":310},[279,1996,1997],{"class":1660}," read_clean",[279,1999,2000],{"class":314},"(path, ",[279,2002,2003],{"class":310},"**",[279,2005,2006],{"class":314},"kwargs):\n",[279,2008,2009,2012,2014,2017,2019],{"class":220,"line":345},[279,2010,2011],{"class":314},"    frame ",[279,2013,351],{"class":310},[279,2015,2016],{"class":314}," pd.read_excel(path, ",[279,2018,2003],{"class":310},[279,2020,2021],{"class":314},"kwargs)\n",[279,2023,2024,2027,2029,2032,2034,2036,2038,2040,2042,2044],{"class":220,"line":552},[279,2025,2026],{"class":314},"    text ",[279,2028,351],{"class":310},[279,2030,2031],{"class":314}," frame.select_dtypes(",[279,2033,1394],{"class":459},[279,2035,351],{"class":310},[279,2037,850],{"class":314},[279,2039,1401],{"class":288},[279,2041,366],{"class":314},[279,2043,1406],{"class":288},[279,2045,1409],{"class":314},[279,2047,2048,2051,2053,2056,2058,2060,2062,2064,2066],{"class":220,"line":699},[279,2049,2050],{"class":314},"    frame[text] ",[279,2052,351],{"class":310},[279,2054,2055],{"class":314}," frame[text].apply(",[279,2057,1422],{"class":310},[279,2059,1425],{"class":314},[279,2061,1428],{"class":288},[279,2063,1431],{"class":314},[279,2065,1434],{"class":380},[279,2067,1322],{"class":314},[279,2069,2070,2072,2074,2077,2079,2081,2083,2085,2087,2089,2091],{"class":220,"line":710},[279,2071,2011],{"class":314},[279,2073,351],{"class":310},[279,2075,2076],{"class":314}," frame.dropna(",[279,2078,1356],{"class":459},[279,2080,351],{"class":310},[279,2082,159],{"class":380},[279,2084,366],{"class":314},[279,2086,1365],{"class":459},[279,2088,351],{"class":310},[279,2090,1370],{"class":288},[279,2092,468],{"class":314},[279,2094,2095,2098,2100,2103,2105,2107,2109,2112,2114,2116,2118,2120],{"class":220,"line":715},[279,2096,2097],{"class":314},"    leftover ",[279,2099,351],{"class":310},[279,2101,2102],{"class":314}," [c ",[279,2104,1683],{"class":310},[279,2106,1737],{"class":314},[279,2108,1689],{"class":310},[279,2110,2111],{"class":314}," frame.columns ",[279,2113,1695],{"class":310},[279,2115,1313],{"class":380},[279,2117,1316],{"class":314},[279,2119,1319],{"class":288},[279,2121,1708],{"class":314},[279,2123,2124,2127],{"class":220,"line":729},[279,2125,2126],{"class":310},"    if",[279,2128,2129],{"class":314}," leftover:\n",[279,2131,2132,2135,2138,2141,2144,2147,2151,2154,2157,2160],{"class":220,"line":737},[279,2133,2134],{"class":310},"        raise",[279,2136,2137],{"class":380}," ValueError",[279,2139,2140],{"class":314},"(",[279,2142,2143],{"class":310},"f",[279,2145,2146],{"class":288},"\"unnamed columns hold data: ",[279,2148,2150],{"class":2149},"sSjpA","{",[279,2152,2153],{"class":314},"leftover",[279,2155,2156],{"class":2149},"}",[279,2158,2159],{"class":288}," — name them in the sheet or pass names=\"",[279,2161,468],{"class":314},[279,2163,2164,2167,2169,2172,2175,2178],{"class":220,"line":1230},[279,2165,2166],{"class":314},"    missing ",[279,2168,351],{"class":310},[279,2170,2171],{"class":380}," REQUIRED",[279,2173,2174],{"class":310}," -",[279,2176,2177],{"class":380}," set",[279,2179,2180],{"class":314},"(frame.columns)\n",[279,2182,2183,2185],{"class":220,"line":1244},[279,2184,2126],{"class":310},[279,2186,2187],{"class":314}," missing:\n",[279,2189,2190,2192,2194,2196,2198,2201,2203,2206,2209,2211,2214],{"class":220,"line":1252},[279,2191,2134],{"class":310},[279,2193,2137],{"class":380},[279,2195,2140],{"class":314},[279,2197,2143],{"class":310},[279,2199,2200],{"class":288},"\"missing columns: ",[279,2202,2150],{"class":2149},[279,2204,2205],{"class":380},"sorted",[279,2207,2208],{"class":314},"(missing)",[279,2210,2156],{"class":2149},[279,2212,2213],{"class":288},"\"",[279,2215,468],{"class":314},[279,2217,2219,2221],{"class":220,"line":2218},14,[279,2220,1713],{"class":310},[279,2222,2223],{"class":314}," frame\n",[279,2225,2227],{"class":220,"line":2226},15,[279,2228,342],{"emptyLinePlaceholder":341},[279,2230,2232,2234,2237,2239],{"class":220,"line":2231},16,[279,2233,427],{"class":380},[279,2235,2236],{"class":314},"(read_clean(",[279,2238,1221],{"class":288},[279,2240,435],{"class":314},[279,2242,2244],{"class":220,"line":2243},17,[279,2245,1334],{"class":421},[10,2247,2248],{},"Raising on leftover unnamed columns is deliberate. A column of data under a blank heading is a question for the person who owns the sheet, and a clear error message gets it asked, where a silent drop would have removed the data from every report downstream.",[267,2250,2252],{"id":2251},"common-pitfalls","Common pitfalls",[2254,2255,2256,2268,2278,2301,2311],"ul",{},[2257,2258,2259,2263,2264,2267],"li",{},[2260,2261,2262],"strong",{},"Renaming by the generated name."," ",[22,2265,2266],{},"rename(columns={\"Unnamed: 2\": \"flag\"})"," works until a column is inserted to its left. Rename by position, or better, get the heading typed into the sheet.",[2257,2269,2270,2277],{},[2260,2271,2272,2273,2276],{},"Treating ",[22,2274,2275],{},"index_col=0"," as a universal fix."," It turns column A into the index whatever it holds. On a sheet where column A is real data with a heading, that moves the data out of the columns.",[2257,2279,2280,2286,2287,2289,2290,2293,2294,2296,2297,2300],{},[2260,2281,2282,2283,2285],{},"Forgetting ",[22,2284,587],{}," on the next write."," Reading with ",[22,2288,2275],{},", modifying, and writing with the default ",[22,2291,2292],{},"index=True"," round-trips correctly — but reading without ",[22,2295,536],{}," and writing with the index adds a ",[45,2298,2299],{},"second"," unnamed column each cycle.",[2257,2302,2303,2306,2307,2310],{},[2260,2304,2305],{},"Stray whitespace."," A single space keeps a column alive through ",[22,2308,2309],{},"dropna",". Strip first.",[2257,2312,2313,2263,2316,2318,2319,581,2321,2323],{},[2260,2314,2315],{},"CSV exports of the same data.",[22,2317,576],{}," has the same default; ",[22,2320,580],{},[22,2322,572],{},". The fixes are identical.",[267,2325,2327],{"id":2326},"performance-notes","Performance notes",[10,2329,2330,2331,2333,2334,1761],{},"None of these fixes costs anything noticeable on normal sheets. The one worth thinking about on large files is ",[22,2332,1261],{},": it is applied while parsing, so columns you exclude are never converted into Python objects, which saves memory as well as a clean-up step. Dropping columns after reading means pandas first built them in full. For a used range that stretches to column XFD because of a formatted whole row, the difference is large — see ",[50,2335,2337],{"href":2336},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-large-excel-files-in-python\u002Freduce-memory-when-reading-excel-with-pandas\u002F","Reduce Memory When Reading Excel with pandas",[267,2339,2341],{"id":2340},"conclusion","Conclusion",[10,2343,2344,2347,2348,2350,2351,2353,2354,2356,2357,2359,2360,2362],{},[22,2345,2346],{},"Unnamed:"," is pandas telling you a header cell was empty. A saved index in column A wants ",[22,2349,2275],{}," or ",[22,2352,587],{},"; a blank heading over real data wants a name, given by position or with ",[22,2355,815],{},"; formatted empty columns want ",[22,2358,1261],{}," or an all-empty drop after stripping text; and ",[22,2361,1484],{}," names come from gaps in a multi-row header and want flattening. Put the rules in one reading function that refuses to drop columns holding data, and the phantom columns stop reaching your reports.",[267,2364,2366],{"id":2365},"frequently-asked-questions","Frequently asked questions",[10,2368,2369,2372],{},[2260,2370,2371],{},"Why does pandas add an \"Unnamed: 0\" column when I read my own file back?","\nThe file was written with to_excel() and the default index=True, so column A holds the old index under an empty header cell. Read it back with index_col=0, or write it with index=False in the first place.",[10,2374,2375,2378],{},[2260,2376,2377],{},"Is it safe to drop every column whose name starts with \"Unnamed\"?","\nOnly after checking what is in them. A blank header above real data is common in hand-built sheets, and dropping by name throws that data away. Drop columns that are completely empty, and rename the ones that hold values.",[10,2380,2381,2384],{},[2260,2382,2383],{},"Why does dropna(axis=1, how=\"all\") leave some Unnamed columns behind?","\nThose columns contain something that is not NaN — usually a cell holding a single space or an empty string typed by someone. Strip strings and turn empty text into NaN first, then drop the all-empty columns.",[10,2386,2387,2390,2391,2394],{},[2260,2388,2389],{},"What does \"Unnamed: 0_level_1\" mean?","\nIt comes from a multi-row header read with header=",[279,2392,2393],{},"0, 1",". The second header row had a blank cell under a merged or filled first-row label, so pandas invented a name for that level. Rename the column tuples or flatten the header after reading.",[267,2396,2398],{"id":2397},"related","Related",[2254,2400,2401,2407,2414,2424],{},[2257,2402,2403,2404,2406],{},"Up one level: ",[50,2405,53],{"href":52}," — the other errors that interrupt reading and writing.",[2257,2408,2409,2413],{},[50,2410,2412],{"href":2411},"\u002Fgetting-started-with-python-excel-automation\u002Freading-excel-files-with-pandas\u002Fskip-rows-and-set-header-when-reading-excel-with-pandas\u002F","Skip Rows and Set the Header When Reading Excel with pandas"," — when the header is not on row 1 at all.",[2257,2415,2416,2420,2421,2423],{},[50,2417,2419],{"href":2418},"\u002Fgetting-started-with-python-excel-automation\u002Freading-excel-files-with-pandas\u002Fread-specific-columns-from-excel-with-pandas\u002F","Read Specific Columns From Excel With Pandas"," — ",[22,2422,1261],{}," in all its forms.",[2257,2425,2426,2430],{},[50,2427,2429],{"href":2428},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fstandardise-excel-column-names-with-pandas\u002F","Standardise Excel Column Names with pandas"," — the next step once every column has a name.",[2432,2433,2434],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}",{"title":20,"searchDepth":324,"depth":324,"links":2436},[2437,2438,2439,2440,2441,2442,2443,2444,2445,2446,2447],{"id":269,"depth":324,"text":270},{"id":390,"depth":324,"text":391},{"id":596,"depth":324,"text":597},{"id":1079,"depth":324,"text":1080},{"id":1473,"depth":324,"text":1474},{"id":1957,"depth":324,"text":1958},{"id":2251,"depth":324,"text":2252},{"id":2326,"depth":324,"text":2327},{"id":2340,"depth":324,"text":2341},{"id":2365,"depth":324,"text":2366},{"id":2397,"depth":324,"text":2398},"2026-09-25","Columns called \"Unnamed: 0\", \"Unnamed: 3\" or \"Unnamed: 0_level_1\" appear when a header cell is empty. Find which of the four causes produced them and apply the matching fix — index_col, usecols, header rows or a cleanup step.","md",[2452,2454,2456,2458],{"q":2371,"a":2453},"The file was written with to_excel() and the default index=True, so column A holds the old index under an empty header cell. Read it back with index_col=0, or write it with index=False in the first place.",{"q":2377,"a":2455},"Only after checking what is in them. A blank header above real data is common in hand-built sheets, and dropping by name throws that data away. Drop columns that are completely empty, and rename the ones that hold values.",{"q":2383,"a":2457},"Those columns contain something that is not NaN — usually a cell holding a single space or an empty string typed by someone. Strip strings and turn empty text into NaN first, then drop the all-empty columns.",{"q":2389,"a":2459},"It comes from a multi-row header read with header=[0, 1]. The second header row had a blank cell under a merged or filled first-row label, so pandas invented a name for that level. Rename the column tuples or flatten the header after reading.","fix unnamed 0 columns when reading excel with pandas",null,{"breadcrumb":2463},[2464,2467,2470],{"name":2465,"item":2466},"Home","\u002F",{"name":2468,"item":2469},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":53,"item":52},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-unnamed-0-columns-when-reading-excel",{"title":2473,"description":2474},"Fix \"Unnamed: 0\" Columns in pandas read_excel","Why pandas read_excel creates \"Unnamed: 0\" columns and how to fix each cause: a saved index, blank header cells, formatted empty columns and multi-row headers.","fix-unnamed-0-columns-when-reading-excel","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-unnamed-0-columns-when-reading-excel\u002Findex",[2478,2479,2480],"troubleshooting","reading-excel","pandas","how-to","vP0THcqamTg2J-YDTjbU7DgtnRDAqyL1vB0q28EeyRg",[2484,2488],{"title":2485,"path":2486,"stem":2487,"children":-1},"Fix UnicodeDecodeError When Reading CSV Files Saved by Excel","\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-unicodedecodeerror-when-reading-csv-files-saved-by-excel","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-unicodedecodeerror-when-reading-csv-files-saved-by-excel\u002Findex",{"title":2489,"path":2490,"stem":2491,"children":-1},"Fix \"Usecols do not match columns\" in pandas read_excel","\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-usecols-do-not-match-columns-error-in-pandas","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-usecols-do-not-match-columns-error-in-pandas\u002Findex",[2493,2495],{"path":2494,"title":2468},"\u002Fgetting-started-with-python-excel-automation",{"path":2496,"title":53},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors",[],[2499,2503,2506,2509,2512,2515],{"path":2500,"title":2501,"kind":2502},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation\u002Fhandle-permission-denied-when-writing-excel-in-python","Handle Permission Denied When Writing Excel in Python","fix",{"path":2504,"title":2505,"kind":2481},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fwhat-openpyxl-loses-when-saving-an-existing-workbook","What openpyxl Loses When You Save an Existing Workbook",{"path":2507,"title":2508,"kind":2502},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-dates-and-times-in-excel-data\u002Ffix-excel-serial-numbers-showing-instead-of-dates","Fix Excel Serial Numbers Showing Instead of Dates",{"path":2510,"title":2511,"kind":2481},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-dates-and-times-in-excel-data\u002Fhandle-daylight-saving-time-in-excel-timestamps","Handle Daylight Saving Time in Excel Timestamps",{"path":2513,"title":2514,"kind":2481},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fhandle-microsoft-graph-throttling-for-excel","Handle Microsoft Graph Throttling in Excel Automation",{"path":2516,"title":2517,"kind":2518},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation","Error Handling and Logging in Excel Automation","guide",1790972067581]