[{"data":1,"prerenderedAt":2106},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-very-wide-dataframes-to-excel":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-very-wide-dataframes-to-excel":2076,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-very-wide-dataframes-to-excel":2081,"children:\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-very-wide-dataframes-to-excel":2086,"related:\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-very-wide-dataframes-to-excel":2087},{"id":4,"title":5,"body":6,"dateModified":2041,"datePublished":2041,"description":2042,"extension":2043,"faq":2044,"keyword":2053,"kind":2054,"meta":2055,"navigation":126,"path":2065,"seo":2066,"slug":2069,"stem":2070,"topics":2071,"type":2074,"__hash__":2075},"docs\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-very-wide-dataframes-to-excel\u002Findex.md","Write Very Wide DataFrames to Excel",{"type":7,"value":8,"toc":2028},"minimark",[9,24,29,60,67,71,419,435,652,656,884,896,900,1034,1041,1045,1264,1279,1354,1358,1759,1766,1770,1785,1907,1911,1948,1952,1962,1966,1972,1978,1987,1993,1997,2024],[10,11,12,13,17,18,23],"p",{},"Most DataFrames are long: many rows, a handful of columns. Some are wide. A sensor export with one column per sensor, a survey with one column per answer option, a pivot with one column per day across several years, or a feature matrix for a model can easily reach tens of thousands of columns. Excel's grid stops at column XFD, the 16,384th, and pandas refuses to write a DataFrame wider than that with ",[14,15,16],"code",{},"ValueError: This sheet is too large!",". There is also a quieter trap just below the limit: pandas checks the DataFrame's own width, not the width it will actually write, so when the index takes an extra column, a frame that \"fits\" loses its last column without any error. This page shows both, measures the real width before writing, and gives three ways to get wide data into a workbook that people can use. It belongs to ",[19,20,22],"a",{"href":21},"\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002F","Writing DataFrames to Excel with pandas",".",[25,26,28],"h2",{"id":27},"prerequisites","Prerequisites",[30,31,36],"pre",{"className":32,"code":33,"language":34,"meta":35,"style":35},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas openpyxl numpy\n","bash","",[14,37,38],{"__ignoreMap":35},[39,40,43,47,51,54,57],"span",{"class":41,"line":42},"line",1,[39,44,46],{"class":45},"sMTad","pip",[39,48,50],{"class":49},"srMev"," install",[39,52,53],{"class":49}," pandas",[39,55,56],{"class":49}," openpyxl",[39,58,59],{"class":49}," numpy\n",[10,61,62,63,66],{},"The limits are the same for every ",[14,64,65],{},".xlsx"," writer: 1,048,576 rows and 16,384 columns per sheet.",[25,68,70],{"id":69},"step-1-the-error-and-the-silent-case","Step 1 — The error, and the silent case",[30,72,76],{"className":73,"code":74,"language":75,"meta":35,"style":35},"language-python shiki shiki-themes github-light github-dark-high-contrast","import numpy as np\nimport pandas as pd\nfrom openpyxl import load_workbook\n\ntoo_wide = pd.DataFrame(np.ones((3, 20_000)))\ntry:\n    too_wide.to_excel(\"too_wide.xlsx\")\nexcept ValueError as e:\n    print(\"ValueError:\", e)\n\njust_fits = pd.DataFrame(np.arange(3 * 16_384).reshape(3, 16_384), columns=[f\"c{i}\" for i in range(16_384)])\njust_fits.to_excel(\"just_fits.xlsx\")                 # index=True by default: needs 16,385 columns\nws = load_workbook(\"just_fits.xlsx\", read_only=True).active\nheader = next(ws.iter_rows(min_row=1, max_row=1, values_only=True))\nprint(\"written columns:\", len(header), \"| last header written:\", header[-1], \"| last in DataFrame:\", just_fits.columns[-1])\n","python",[14,77,78,94,107,121,128,153,162,174,189,204,209,288,304,330,373],{"__ignoreMap":35},[39,79,80,84,88,91],{"class":41,"line":42},[39,81,83],{"class":82},"s-kum","import",[39,85,87],{"class":86},"skGVy"," numpy ",[39,89,90],{"class":82},"as",[39,92,93],{"class":86}," np\n",[39,95,97,99,102,104],{"class":41,"line":96},2,[39,98,83],{"class":82},[39,100,101],{"class":86}," pandas ",[39,103,90],{"class":82},[39,105,106],{"class":86}," pd\n",[39,108,110,113,116,118],{"class":41,"line":109},3,[39,111,112],{"class":82},"from",[39,114,115],{"class":86}," openpyxl ",[39,117,83],{"class":82},[39,119,120],{"class":86}," load_workbook\n",[39,122,124],{"class":41,"line":123},4,[39,125,127],{"emptyLinePlaceholder":126},true,"\n",[39,129,131,134,137,140,144,147,150],{"class":41,"line":130},5,[39,132,133],{"class":86},"too_wide ",[39,135,136],{"class":82},"=",[39,138,139],{"class":86}," pd.DataFrame(np.ones((",[39,141,143],{"class":142},"sP0c6","3",[39,145,146],{"class":86},", ",[39,148,149],{"class":142},"20_000",[39,151,152],{"class":86},")))\n",[39,154,156,159],{"class":41,"line":155},6,[39,157,158],{"class":82},"try",[39,160,161],{"class":86},":\n",[39,163,165,168,171],{"class":41,"line":164},7,[39,166,167],{"class":86},"    too_wide.to_excel(",[39,169,170],{"class":49},"\"too_wide.xlsx\"",[39,172,173],{"class":86},")\n",[39,175,177,180,183,186],{"class":41,"line":176},8,[39,178,179],{"class":82},"except",[39,181,182],{"class":142}," ValueError",[39,184,185],{"class":82}," as",[39,187,188],{"class":86}," e:\n",[39,190,192,195,198,201],{"class":41,"line":191},9,[39,193,194],{"class":142},"    print",[39,196,197],{"class":86},"(",[39,199,200],{"class":49},"\"ValueError:\"",[39,202,203],{"class":86},", e)\n",[39,205,207],{"class":41,"line":206},10,[39,208,127],{"emptyLinePlaceholder":126},[39,210,212,215,217,220,222,225,228,231,233,235,238,241,245,247,250,253,256,260,263,266,269,272,275,278,281,283,285],{"class":41,"line":211},11,[39,213,214],{"class":86},"just_fits ",[39,216,136],{"class":82},[39,218,219],{"class":86}," pd.DataFrame(np.arange(",[39,221,143],{"class":142},[39,223,224],{"class":82}," *",[39,226,227],{"class":142}," 16_384",[39,229,230],{"class":86},").reshape(",[39,232,143],{"class":142},[39,234,146],{"class":86},[39,236,237],{"class":142},"16_384",[39,239,240],{"class":86},"), ",[39,242,244],{"class":243},"sa561","columns",[39,246,136],{"class":82},[39,248,249],{"class":86},"[",[39,251,252],{"class":82},"f",[39,254,255],{"class":49},"\"c",[39,257,259],{"class":258},"sSjpA","{",[39,261,262],{"class":86},"i",[39,264,265],{"class":258},"}",[39,267,268],{"class":49},"\"",[39,270,271],{"class":82}," for",[39,273,274],{"class":86}," i ",[39,276,277],{"class":82},"in",[39,279,280],{"class":142}," range",[39,282,197],{"class":86},[39,284,237],{"class":142},[39,286,287],{"class":86},")])\n",[39,289,291,294,297,300],{"class":41,"line":290},12,[39,292,293],{"class":86},"just_fits.to_excel(",[39,295,296],{"class":49},"\"just_fits.xlsx\"",[39,298,299],{"class":86},")                 ",[39,301,303],{"class":302},"s-wDw","# index=True by default: needs 16,385 columns\n",[39,305,307,310,312,315,317,319,322,324,327],{"class":41,"line":306},13,[39,308,309],{"class":86},"ws ",[39,311,136],{"class":82},[39,313,314],{"class":86}," load_workbook(",[39,316,296],{"class":49},[39,318,146],{"class":86},[39,320,321],{"class":243},"read_only",[39,323,136],{"class":82},[39,325,326],{"class":142},"True",[39,328,329],{"class":86},").active\n",[39,331,333,336,338,341,344,347,349,352,354,357,359,361,363,366,368,370],{"class":41,"line":332},14,[39,334,335],{"class":86},"header ",[39,337,136],{"class":82},[39,339,340],{"class":142}," next",[39,342,343],{"class":86},"(ws.iter_rows(",[39,345,346],{"class":243},"min_row",[39,348,136],{"class":82},[39,350,351],{"class":142},"1",[39,353,146],{"class":86},[39,355,356],{"class":243},"max_row",[39,358,136],{"class":82},[39,360,351],{"class":142},[39,362,146],{"class":86},[39,364,365],{"class":243},"values_only",[39,367,136],{"class":82},[39,369,326],{"class":142},[39,371,372],{"class":86},"))\n",[39,374,376,379,381,384,386,389,392,395,398,401,403,406,409,412,414,416],{"class":41,"line":375},15,[39,377,378],{"class":142},"print",[39,380,197],{"class":86},[39,382,383],{"class":49},"\"written columns:\"",[39,385,146],{"class":86},[39,387,388],{"class":142},"len",[39,390,391],{"class":86},"(header), ",[39,393,394],{"class":49},"\"| last header written:\"",[39,396,397],{"class":86},", header[",[39,399,400],{"class":82},"-",[39,402,351],{"class":142},[39,404,405],{"class":86},"], ",[39,407,408],{"class":49},"\"| last in DataFrame:\"",[39,410,411],{"class":86},", just_fits.columns[",[39,413,400],{"class":82},[39,415,351],{"class":142},[39,417,418],{"class":86},"])\n",[10,420,421,422,425,426,430,431,434],{},"The first case fails loudly: 20,000 columns, and pandas reports the sheet size against the maximum of 1,048,576 × 16,384. The second is the one to worry about. The DataFrame has exactly 16,384 columns, so it passes pandas' check, but ",[14,423,424],{},"to_excel"," writes the index as well, which needs one more column than Excel has. Neither openpyxl nor XlsxWriter complains; the workbook simply ends at column XFD, and the last DataFrame column, ",[427,428,429],"em",{},"c16383",", is not in the file. The same happens with a MultiIndex, which takes one column per level, and with ",[14,432,433],{},"startcol",", which shifts everything right.",[436,437,445,446,445,450,445,454,445,462,445,471,445,475,445,482,445,486,445,490,445,494,445,498,445,502,445,506,445,510,445,514,445,519,445,523,445,525,445,528,445,530,445,533,445,535,445,538,445,541,445,545,445,547,445,551,445,553,445,556,445,558,445,561,445,565,445,569,445,572,445,575,445,577,445,580,445,582,445,585,445,587,445,589,445,593,445,597,445,600,445,604,445,606,445,609,445,611,445,614,445,616,445,619,445,623,445,627,445,630,445,634,445,636,445,639,445,641,445,644,445,646,445,648,445,650],"svg",{"viewBox":438,"role":439,"ariaLabelledBy":440,"xmlns":443,"style":444},"62 0 636 196","img",[441,442],"wide-limits-t","wide-limits-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:636px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[447,448,449],"title",{"id":441},"Where the columns go",[451,452,453],"desc",{"id":442},"Excel has 16,384 columns, A to XFD. A DataFrame of 16,384 columns written with its index needs 16,385, so the last DataFrame column falls beyond XFD and is silently dropped. Without the index it fits exactly.",[455,456],"rect",{"x":457,"y":458,"width":459,"height":460,"fill":461},"62","0","636","196","#ffffff",[455,463],{"x":464,"y":465,"width":466,"height":467,"rx":458,"fill":468,"stroke":469,"style":470},"78.5","16.0","32.0","24.0","#e7ebef","var(--line,#cdd5e6)","stroke-width:1px",[455,472],{"x":473,"y":465,"width":474,"height":467,"rx":458,"fill":468,"stroke":469,"style":470},"110.5","162.1",[476,477,481],"text",{"x":478,"y":479,"style":480},"191.5","33.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[455,483],{"x":484,"y":465,"width":485,"height":467,"rx":458,"fill":468,"stroke":469,"style":470},"272.5","128.0",[476,487,489],{"x":488,"y":479,"style":480},"336.5","B",[455,491],{"x":492,"y":465,"width":493,"height":467,"rx":458,"fill":468,"stroke":469,"style":470},"400.5","112.3",[476,495,497],{"x":496,"y":479,"style":480},"456.6","C",[455,499],{"x":500,"y":465,"width":501,"height":467,"rx":458,"fill":468,"stroke":469,"style":470},"512.8","168.8",[476,503,505],{"x":504,"y":479,"style":480},"597.2","D",[455,507],{"x":464,"y":508,"width":466,"height":509,"rx":458,"fill":468,"stroke":469,"style":470},"40.0","28.0",[476,511,351],{"x":512,"y":513,"style":480},"94.5","59.0",[455,515],{"x":473,"y":508,"width":474,"height":509,"rx":458,"fill":516,"stroke":517,"style":518},"#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.5px",[476,520,522],{"x":478,"y":513,"style":521},"font-size:12px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Written",[455,524],{"x":484,"y":508,"width":485,"height":509,"rx":458,"fill":516,"stroke":517,"style":518},[476,526,527],{"x":488,"y":513,"style":521},"Columns needed",[455,529],{"x":492,"y":508,"width":493,"height":509,"rx":458,"fill":516,"stroke":517,"style":518},[476,531,532],{"x":496,"y":513,"style":521},"Fits in A–XFD?",[455,534],{"x":500,"y":508,"width":501,"height":509,"rx":458,"fill":516,"stroke":517,"style":518},[476,536,537],{"x":504,"y":513,"style":521},"Result",[455,539],{"x":464,"y":540,"width":466,"height":509,"rx":458,"fill":468,"stroke":469,"style":470},"68.0",[476,542,544],{"x":512,"y":543,"style":480},"87.0","2",[455,546],{"x":473,"y":540,"width":474,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,548,550],{"x":478,"y":543,"style":549},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","20,000 columns",[455,552],{"x":484,"y":540,"width":485,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,554,555],{"x":488,"y":543,"style":549},"20,001",[455,557],{"x":492,"y":540,"width":493,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,559,560],{"x":496,"y":543,"style":549},"no",[455,562],{"x":500,"y":540,"width":501,"height":509,"rx":458,"fill":563,"stroke":564,"style":518},"#fdefd8","var(--gold,#b4740a)",[476,566,568],{"x":504,"y":543,"style":567},"font-size:12px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","ValueError",[455,570],{"x":464,"y":571,"width":466,"height":509,"rx":458,"fill":468,"stroke":469,"style":470},"96.0",[476,573,143],{"x":512,"y":574,"style":480},"115.0",[455,576],{"x":473,"y":571,"width":474,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,578,579],{"x":478,"y":574,"style":549},"16,384 + index",[455,581],{"x":484,"y":571,"width":485,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,583,584],{"x":488,"y":574,"style":549},"16,385",[455,586],{"x":492,"y":571,"width":493,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,588,560],{"x":496,"y":574,"style":549},[455,590],{"x":500,"y":571,"width":501,"height":509,"rx":458,"fill":591,"stroke":592,"style":518},"#fce9e9","var(--danger,#dc2626)",[476,594,596],{"x":504,"y":574,"style":595},"font-size:12px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","last column lost silently",[455,598],{"x":464,"y":599,"width":466,"height":509,"rx":458,"fill":468,"stroke":469,"style":470},"124.0",[476,601,603],{"x":512,"y":602,"style":480},"143.0","4",[455,605],{"x":473,"y":599,"width":474,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,607,608],{"x":478,"y":602,"style":549},"16,384, index=False",[455,610],{"x":484,"y":599,"width":485,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,612,613],{"x":488,"y":602,"style":549},"16,384",[455,615],{"x":492,"y":599,"width":493,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,617,618],{"x":496,"y":602,"style":549},"yes",[455,620],{"x":500,"y":599,"width":501,"height":509,"rx":458,"fill":621,"stroke":622,"style":518},"#d9f4f1","var(--teal,#0f9488)",[476,624,626],{"x":504,"y":602,"style":625},"font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","complete",[455,628],{"x":464,"y":629,"width":466,"height":509,"rx":458,"fill":468,"stroke":469,"style":470},"152.0",[476,631,633],{"x":512,"y":632,"style":480},"171.0","5",[455,635],{"x":473,"y":629,"width":474,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,637,638],{"x":478,"y":632,"style":549},"16,000 + 2-level index",[455,640],{"x":484,"y":629,"width":485,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,642,643],{"x":488,"y":632,"style":549},"16,002",[455,645],{"x":492,"y":629,"width":493,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,647,618],{"x":496,"y":632,"style":549},[455,649],{"x":500,"y":629,"width":501,"height":509,"rx":458,"fill":461,"stroke":469,"style":470},[476,651,626],{"x":504,"y":632,"style":549},[25,653,655],{"id":654},"step-2-measure-the-real-width-before-writing","Step 2 — Measure the real width before writing",[30,657,659],{"className":73,"code":658,"language":75,"meta":35,"style":35},"MAX_COLS = 16_384\n\ndef written_width(df, index=True, startcol=0):\n    return startcol + df.shape[1] + (df.index.nlevels if index else 0)\n\nfor name, df, idx in [(\"too_wide\", too_wide, True), (\"just_fits\", just_fits, True), (\"just_fits\", just_fits, False)]:\n    w = written_width(df, index=idx)\n    print(f\"{name:9} index={idx!s:5} needs {w:>6,} columns -> {'OK' if w \u003C= MAX_COLS else 'TOO WIDE'}\")\n",[14,660,661,672,676,702,740,744,788,806],{"__ignoreMap":35},[39,662,663,666,669],{"class":41,"line":42},[39,664,665],{"class":142},"MAX_COLS",[39,667,668],{"class":82}," =",[39,670,671],{"class":142}," 16_384\n",[39,673,674],{"class":41,"line":96},[39,675,127],{"emptyLinePlaceholder":126},[39,677,678,681,685,688,690,692,695,697,699],{"class":41,"line":109},[39,679,680],{"class":82},"def",[39,682,684],{"class":683},"s_Opv"," written_width",[39,686,687],{"class":86},"(df, index",[39,689,136],{"class":82},[39,691,326],{"class":142},[39,693,694],{"class":86},", startcol",[39,696,136],{"class":82},[39,698,458],{"class":142},[39,700,701],{"class":86},"):\n",[39,703,704,707,710,713,716,718,721,723,726,729,732,735,738],{"class":41,"line":123},[39,705,706],{"class":82},"    return",[39,708,709],{"class":86}," startcol ",[39,711,712],{"class":82},"+",[39,714,715],{"class":86}," df.shape[",[39,717,351],{"class":142},[39,719,720],{"class":86},"] ",[39,722,712],{"class":82},[39,724,725],{"class":86}," (df.index.nlevels ",[39,727,728],{"class":82},"if",[39,730,731],{"class":86}," index ",[39,733,734],{"class":82},"else",[39,736,737],{"class":142}," 0",[39,739,173],{"class":86},[39,741,742],{"class":41,"line":130},[39,743,127],{"emptyLinePlaceholder":126},[39,745,746,749,752,754,757,760,763,765,768,771,774,776,778,780,782,785],{"class":41,"line":155},[39,747,748],{"class":82},"for",[39,750,751],{"class":86}," name, df, idx ",[39,753,277],{"class":82},[39,755,756],{"class":86}," [(",[39,758,759],{"class":49},"\"too_wide\"",[39,761,762],{"class":86},", too_wide, ",[39,764,326],{"class":142},[39,766,767],{"class":86},"), (",[39,769,770],{"class":49},"\"just_fits\"",[39,772,773],{"class":86},", just_fits, ",[39,775,326],{"class":142},[39,777,767],{"class":86},[39,779,770],{"class":49},[39,781,773],{"class":86},[39,783,784],{"class":142},"False",[39,786,787],{"class":86},")]:\n",[39,789,790,793,795,798,801,803],{"class":41,"line":164},[39,791,792],{"class":86},"    w ",[39,794,136],{"class":82},[39,796,797],{"class":86}," written_width(df, ",[39,799,800],{"class":243},"index",[39,802,136],{"class":82},[39,804,805],{"class":86},"idx)\n",[39,807,808,810,812,814,816,818,821,824,826,829,831,834,837,839,842,844,847,850,852,855,857,860,863,866,869,872,875,878,880,882],{"class":41,"line":176},[39,809,194],{"class":142},[39,811,197],{"class":86},[39,813,252],{"class":82},[39,815,268],{"class":49},[39,817,259],{"class":258},[39,819,820],{"class":86},"name",[39,822,823],{"class":82},":9",[39,825,265],{"class":258},[39,827,828],{"class":49}," index=",[39,830,259],{"class":258},[39,832,833],{"class":86},"idx",[39,835,836],{"class":82},"!s:5",[39,838,265],{"class":258},[39,840,841],{"class":49}," needs ",[39,843,259],{"class":258},[39,845,846],{"class":86},"w",[39,848,849],{"class":82},":>6,",[39,851,265],{"class":258},[39,853,854],{"class":49}," columns -> ",[39,856,259],{"class":258},[39,858,859],{"class":49},"'OK'",[39,861,862],{"class":82}," if",[39,864,865],{"class":86}," w ",[39,867,868],{"class":82},"\u003C=",[39,870,871],{"class":142}," MAX_COLS",[39,873,874],{"class":82}," else",[39,876,877],{"class":49}," 'TOO WIDE'",[39,879,265],{"class":258},[39,881,268],{"class":49},[39,883,173],{"class":86},[10,885,886,887,889,890,892,893,23],{},"The width that matters is the DataFrame's columns plus one column per index level, if the index is written, plus any ",[14,888,433],{}," offset. A three-line function gives that number, and a guard that raises when it exceeds 16,384 turns the silent loss into an error. Put the check next to every ",[14,891,424],{}," call that might see wide data — it costs nothing and catches the case pandas misses. The output confirms the arithmetic: the frame of exactly 16,384 columns needs 16,385 with its index, and fits only with ",[14,894,895],{},"index=False",[25,897,899],{"id":898},"step-3-short-and-wide-transpose-it","Step 3 — Short and wide: transpose it",[30,901,903],{"className":73,"code":902,"language":75,"meta":35,"style":35},"sensors = pd.DataFrame(np.random.default_rng(1).normal(20, 2, (3, 18_000)).round(2),\n                       index=[\"min\", \"mean\", \"max\"], columns=[f\"S{i:05d}\" for i in range(18_000)])\nsensors.T.rename_axis(\"Sensor\").to_excel(\"sensor_summary.xlsx\")\nprint(sensors.shape, \"->\", sensors.T.shape)\n",[14,904,905,945,1005,1021],{"__ignoreMap":35},[39,906,907,910,912,915,917,920,923,925,927,930,932,934,937,940,942],{"class":41,"line":42},[39,908,909],{"class":86},"sensors ",[39,911,136],{"class":82},[39,913,914],{"class":86}," pd.DataFrame(np.random.default_rng(",[39,916,351],{"class":142},[39,918,919],{"class":86},").normal(",[39,921,922],{"class":142},"20",[39,924,146],{"class":86},[39,926,544],{"class":142},[39,928,929],{"class":86},", (",[39,931,143],{"class":142},[39,933,146],{"class":86},[39,935,936],{"class":142},"18_000",[39,938,939],{"class":86},")).round(",[39,941,544],{"class":142},[39,943,944],{"class":86},"),\n",[39,946,947,950,952,954,957,959,962,964,967,969,971,973,975,977,980,982,984,987,989,991,993,995,997,999,1001,1003],{"class":41,"line":96},[39,948,949],{"class":243},"                       index",[39,951,136],{"class":82},[39,953,249],{"class":86},[39,955,956],{"class":49},"\"min\"",[39,958,146],{"class":86},[39,960,961],{"class":49},"\"mean\"",[39,963,146],{"class":86},[39,965,966],{"class":49},"\"max\"",[39,968,405],{"class":86},[39,970,244],{"class":243},[39,972,136],{"class":82},[39,974,249],{"class":86},[39,976,252],{"class":82},[39,978,979],{"class":49},"\"S",[39,981,259],{"class":258},[39,983,262],{"class":86},[39,985,986],{"class":82},":05d",[39,988,265],{"class":258},[39,990,268],{"class":49},[39,992,271],{"class":82},[39,994,274],{"class":86},[39,996,277],{"class":82},[39,998,280],{"class":142},[39,1000,197],{"class":86},[39,1002,936],{"class":142},[39,1004,287],{"class":86},[39,1006,1007,1010,1013,1016,1019],{"class":41,"line":109},[39,1008,1009],{"class":86},"sensors.T.rename_axis(",[39,1011,1012],{"class":49},"\"Sensor\"",[39,1014,1015],{"class":86},").to_excel(",[39,1017,1018],{"class":49},"\"sensor_summary.xlsx\"",[39,1020,173],{"class":86},[39,1022,1023,1025,1028,1031],{"class":41,"line":123},[39,1024,378],{"class":142},[39,1026,1027],{"class":86},"(sensors.shape, ",[39,1029,1030],{"class":49},"\"->\"",[39,1032,1033],{"class":86},", sensors.T.shape)\n",[10,1035,1036,1037,1040],{},"When there are few rows and many columns — a summary of three statistics for 18,000 sensors — the data is simply lying on its side. Transposing turns 18,000 columns into 18,000 rows and three columns, well within the limits, and it is also far easier to read: a reader can sort and filter by sensor, which Excel does along rows, not columns. Naming the new index ",[427,1038,1039],{},"Sensor"," gives the first column a proper heading.",[25,1042,1044],{"id":1043},"step-4-wide-time-series-melt-to-long-format","Step 4 — Wide time series: melt to long format",[30,1046,1048],{"className":73,"code":1047,"language":75,"meta":35,"style":35},"days = pd.date_range(\"2000-01-01\", periods=9_500, freq=\"D\")\nprices = pd.DataFrame(np.random.default_rng(2).normal(100, 5, (4, len(days))).round(2),\n                      index=pd.Index([\"A\", \"B\", \"C\", \"D\"], name=\"Product\"), columns=days)\nlong = prices.reset_index().melt(id_vars=\"Product\", var_name=\"Date\", value_name=\"Price\")\nlong.to_excel(\"prices_long.xlsx\", index=False)\nprint(prices.shape, \"->\", long.shape)\nprint(long.head(3).to_string(index=False))\n",[14,1049,1050,1085,1120,1165,1204,1224,1240],{"__ignoreMap":35},[39,1051,1052,1055,1057,1060,1063,1065,1068,1070,1073,1075,1078,1080,1083],{"class":41,"line":42},[39,1053,1054],{"class":86},"days ",[39,1056,136],{"class":82},[39,1058,1059],{"class":86}," pd.date_range(",[39,1061,1062],{"class":49},"\"2000-01-01\"",[39,1064,146],{"class":86},[39,1066,1067],{"class":243},"periods",[39,1069,136],{"class":82},[39,1071,1072],{"class":142},"9_500",[39,1074,146],{"class":86},[39,1076,1077],{"class":243},"freq",[39,1079,136],{"class":82},[39,1081,1082],{"class":49},"\"D\"",[39,1084,173],{"class":86},[39,1086,1087,1090,1092,1094,1096,1098,1101,1103,1105,1107,1109,1111,1113,1116,1118],{"class":41,"line":96},[39,1088,1089],{"class":86},"prices ",[39,1091,136],{"class":82},[39,1093,914],{"class":86},[39,1095,544],{"class":142},[39,1097,919],{"class":86},[39,1099,1100],{"class":142},"100",[39,1102,146],{"class":86},[39,1104,633],{"class":142},[39,1106,929],{"class":86},[39,1108,603],{"class":142},[39,1110,146],{"class":86},[39,1112,388],{"class":142},[39,1114,1115],{"class":86},"(days))).round(",[39,1117,544],{"class":142},[39,1119,944],{"class":86},[39,1121,1122,1125,1127,1130,1133,1135,1138,1140,1143,1145,1147,1149,1151,1153,1156,1158,1160,1162],{"class":41,"line":109},[39,1123,1124],{"class":243},"                      index",[39,1126,136],{"class":82},[39,1128,1129],{"class":86},"pd.Index([",[39,1131,1132],{"class":49},"\"A\"",[39,1134,146],{"class":86},[39,1136,1137],{"class":49},"\"B\"",[39,1139,146],{"class":86},[39,1141,1142],{"class":49},"\"C\"",[39,1144,146],{"class":86},[39,1146,1082],{"class":49},[39,1148,405],{"class":86},[39,1150,820],{"class":243},[39,1152,136],{"class":82},[39,1154,1155],{"class":49},"\"Product\"",[39,1157,240],{"class":86},[39,1159,244],{"class":243},[39,1161,136],{"class":82},[39,1163,1164],{"class":86},"days)\n",[39,1166,1167,1170,1172,1175,1178,1180,1182,1184,1187,1189,1192,1194,1197,1199,1202],{"class":41,"line":123},[39,1168,1169],{"class":243},"long",[39,1171,668],{"class":82},[39,1173,1174],{"class":86}," prices.reset_index().melt(",[39,1176,1177],{"class":243},"id_vars",[39,1179,136],{"class":82},[39,1181,1155],{"class":49},[39,1183,146],{"class":86},[39,1185,1186],{"class":243},"var_name",[39,1188,136],{"class":82},[39,1190,1191],{"class":49},"\"Date\"",[39,1193,146],{"class":86},[39,1195,1196],{"class":243},"value_name",[39,1198,136],{"class":82},[39,1200,1201],{"class":49},"\"Price\"",[39,1203,173],{"class":86},[39,1205,1206,1208,1211,1214,1216,1218,1220,1222],{"class":41,"line":130},[39,1207,1169],{"class":243},[39,1209,1210],{"class":86},".to_excel(",[39,1212,1213],{"class":49},"\"prices_long.xlsx\"",[39,1215,146],{"class":86},[39,1217,800],{"class":243},[39,1219,136],{"class":82},[39,1221,784],{"class":142},[39,1223,173],{"class":86},[39,1225,1226,1228,1231,1233,1235,1237],{"class":41,"line":155},[39,1227,378],{"class":142},[39,1229,1230],{"class":86},"(prices.shape, ",[39,1232,1030],{"class":49},[39,1234,146],{"class":86},[39,1236,1169],{"class":243},[39,1238,1239],{"class":86},".shape)\n",[39,1241,1242,1244,1246,1248,1251,1253,1256,1258,1260,1262],{"class":41,"line":164},[39,1243,378],{"class":142},[39,1245,197],{"class":86},[39,1247,1169],{"class":243},[39,1249,1250],{"class":86},".head(",[39,1252,143],{"class":142},[39,1254,1255],{"class":86},").to_string(",[39,1257,800],{"class":243},[39,1259,136],{"class":82},[39,1261,784],{"class":142},[39,1263,372],{"class":86},[10,1265,1266,1267,1270,1271,1274,1275,23],{},"A pivot with one column per day becomes too wide after about 45 years of daily data — or much sooner if each day has several measures. Long format, with one row per product and date, has three columns however many days there are, and up to a million rows. It is the shape pivot tables, Power Query, charts and pandas all prefer, so the reader loses nothing: a pivot table in Excel turns it back into the wide view with a few clicks. ",[14,1268,1269],{},"melt"," does the reshaping; the reverse is a ",[14,1272,1273],{},"pivot",", covered in ",[19,1276,1278],{"href":1277},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Funpivot-a-wide-excel-sheet-with-pandas-melt\u002F","Unpivot a Wide Excel Sheet with pandas melt",[436,1280,445,1286,445,1289,445,1292,445,1296,445,1303,445,1309,445,1314,445,1318,445,1322,445,1326,445,1330,445,1333,445,1338,445,1342,445,1345,445,1348,445,1351],{"viewBox":1281,"role":439,"ariaLabelledBy":1282,"xmlns":443,"style":1285},"4 0 752 199",[1283,1284],"wide-reshape-t","wide-reshape-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[447,1287,1288],{"id":1283},"Transpose or melt",[451,1290,1291],{"id":1284},"Transpose suits short and wide data such as a few statistics for many items, turning columns into rows. Melt suits wide data with a row key, such as one column per date, turning it into one row per key and column.",[455,1293],{"x":603,"y":458,"width":1294,"height":1295,"fill":461},"752","199",[455,1297],{"x":1298,"y":465,"width":1299,"height":1300,"rx":1301,"fill":621,"stroke":622,"style":1302},"20.0","351.0","167.0","14","stroke-width:2px",[476,1304,1308],{"x":1305,"y":1306,"style":1307},"195.5","44.0","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Transpose",[41,1310],{"x1":1311,"y1":1312,"x2":1313,"y2":1312,"stroke":622,"style":470},"36.0","57.0","355.0",[476,1315,1317],{"x":1305,"y":1316,"style":549},"77.0","few rows, many columns",[476,1319,1321],{"x":1305,"y":1320,"style":549},"103.0","columns become rows",[476,1323,1325],{"x":1305,"y":1324,"style":549},"129.0","3 × 18,000 → 18,000 × 3",[476,1327,1329],{"x":1305,"y":1328,"style":549},"155.0","easy to sort and filter",[455,1331],{"x":1332,"y":465,"width":1299,"height":1300,"rx":1301,"fill":516,"stroke":517,"style":1302},"389.0",[476,1334,1337],{"x":1335,"y":1306,"style":1336},"564.5","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Melt to long format",[41,1339],{"x1":1340,"y1":1312,"x2":1341,"y2":1312,"stroke":517,"style":470},"405.0","724.0",[476,1343,1344],{"x":1335,"y":1316,"style":549},"one column per date or item",[476,1346,1347],{"x":1335,"y":1320,"style":549},"one row per key and column",[476,1349,1350],{"x":1335,"y":1324,"style":549},"4 × 9,500 → 38,000 × 3",[476,1352,1353],{"x":1335,"y":1328,"style":549},"pivot it back in Excel",[25,1355,1357],{"id":1356},"step-5-keep-it-wide-split-across-sheets","Step 5 — Keep it wide: split across sheets",[30,1359,1361],{"className":73,"code":1360,"language":75,"meta":35,"style":35},"def write_wide(df, path, key_cols=1, chunk=16_000):\n    \"\"\"Split the value columns into blocks, repeating the key columns on every sheet.\"\"\"\n    keys, values = df.iloc[:, :key_cols], df.iloc[:, key_cols:]\n    with pd.ExcelWriter(path) as xw:\n        for n, start in enumerate(range(0, values.shape[1], chunk), start=1):\n            block = pd.concat([keys, values.iloc[:, start:start + chunk]], axis=1)\n            assert written_width(block, index=False) \u003C= MAX_COLS\n            block.to_excel(xw, sheet_name=f\"Cols {start + 1}-{start + block.shape[1] - key_cols}\", index=False)\n    return n\n\nmatrix = pd.concat([pd.Series([\"r1\", \"r2\"], name=\"Row\"),\n                    pd.DataFrame(np.ones((2, 40_000), dtype=int), columns=[f\"f{i}\" for i in range(40_000)])], axis=1)\nsheets = write_wide(matrix, \"feature_matrix.xlsx\")\nwith pd.ExcelFile(\"feature_matrix.xlsx\") as book:\n    print(sheets, \"sheets:\", book.sheet_names)\n    print(sum(book.parse(s).shape[1] - 1 for s in book.sheet_names), \"value columns written of\", matrix.shape[1] - 1)\n",[14,1362,1363,1387,1392,1402,1415,1454,1478,1500,1561,1568,1572,1601,1667,1682,1699,1712],{"__ignoreMap":35},[39,1364,1365,1367,1370,1373,1375,1377,1380,1382,1385],{"class":41,"line":42},[39,1366,680],{"class":82},[39,1368,1369],{"class":683}," write_wide",[39,1371,1372],{"class":86},"(df, path, key_cols",[39,1374,136],{"class":82},[39,1376,351],{"class":142},[39,1378,1379],{"class":86},", chunk",[39,1381,136],{"class":82},[39,1383,1384],{"class":142},"16_000",[39,1386,701],{"class":86},[39,1388,1389],{"class":41,"line":96},[39,1390,1391],{"class":49},"    \"\"\"Split the value columns into blocks, repeating the key columns on every sheet.\"\"\"\n",[39,1393,1394,1397,1399],{"class":41,"line":109},[39,1395,1396],{"class":86},"    keys, values ",[39,1398,136],{"class":82},[39,1400,1401],{"class":86}," df.iloc[:, :key_cols], df.iloc[:, key_cols:]\n",[39,1403,1404,1407,1410,1412],{"class":41,"line":123},[39,1405,1406],{"class":82},"    with",[39,1408,1409],{"class":86}," pd.ExcelWriter(path) ",[39,1411,90],{"class":82},[39,1413,1414],{"class":86}," xw:\n",[39,1416,1417,1420,1423,1425,1428,1430,1433,1435,1437,1440,1442,1445,1448,1450,1452],{"class":41,"line":130},[39,1418,1419],{"class":82},"        for",[39,1421,1422],{"class":86}," n, start ",[39,1424,277],{"class":82},[39,1426,1427],{"class":142}," enumerate",[39,1429,197],{"class":86},[39,1431,1432],{"class":142},"range",[39,1434,197],{"class":86},[39,1436,458],{"class":142},[39,1438,1439],{"class":86},", values.shape[",[39,1441,351],{"class":142},[39,1443,1444],{"class":86},"], chunk), ",[39,1446,1447],{"class":243},"start",[39,1449,136],{"class":82},[39,1451,351],{"class":142},[39,1453,701],{"class":86},[39,1455,1456,1459,1461,1464,1466,1469,1472,1474,1476],{"class":41,"line":155},[39,1457,1458],{"class":86},"            block ",[39,1460,136],{"class":82},[39,1462,1463],{"class":86}," pd.concat([keys, values.iloc[:, start:start ",[39,1465,712],{"class":82},[39,1467,1468],{"class":86}," chunk]], ",[39,1470,1471],{"class":243},"axis",[39,1473,136],{"class":82},[39,1475,351],{"class":142},[39,1477,173],{"class":86},[39,1479,1480,1483,1486,1488,1490,1492,1495,1497],{"class":41,"line":164},[39,1481,1482],{"class":82},"            assert",[39,1484,1485],{"class":86}," written_width(block, ",[39,1487,800],{"class":243},[39,1489,136],{"class":82},[39,1491,784],{"class":142},[39,1493,1494],{"class":86},") ",[39,1496,868],{"class":82},[39,1498,1499],{"class":142}," MAX_COLS\n",[39,1501,1502,1505,1508,1510,1512,1515,1517,1520,1522,1525,1527,1529,1531,1533,1535,1538,1540,1542,1544,1547,1549,1551,1553,1555,1557,1559],{"class":41,"line":176},[39,1503,1504],{"class":86},"            block.to_excel(xw, ",[39,1506,1507],{"class":243},"sheet_name",[39,1509,136],{"class":82},[39,1511,252],{"class":82},[39,1513,1514],{"class":49},"\"Cols ",[39,1516,259],{"class":258},[39,1518,1519],{"class":86},"start ",[39,1521,712],{"class":82},[39,1523,1524],{"class":142}," 1",[39,1526,265],{"class":258},[39,1528,400],{"class":49},[39,1530,259],{"class":258},[39,1532,1519],{"class":86},[39,1534,712],{"class":82},[39,1536,1537],{"class":86}," block.shape[",[39,1539,351],{"class":142},[39,1541,720],{"class":86},[39,1543,400],{"class":82},[39,1545,1546],{"class":86}," key_cols",[39,1548,265],{"class":258},[39,1550,268],{"class":49},[39,1552,146],{"class":86},[39,1554,800],{"class":243},[39,1556,136],{"class":82},[39,1558,784],{"class":142},[39,1560,173],{"class":86},[39,1562,1563,1565],{"class":41,"line":191},[39,1564,706],{"class":82},[39,1566,1567],{"class":86}," n\n",[39,1569,1570],{"class":41,"line":206},[39,1571,127],{"emptyLinePlaceholder":126},[39,1573,1574,1577,1579,1582,1585,1587,1590,1592,1594,1596,1599],{"class":41,"line":211},[39,1575,1576],{"class":86},"matrix ",[39,1578,136],{"class":82},[39,1580,1581],{"class":86}," pd.concat([pd.Series([",[39,1583,1584],{"class":49},"\"r1\"",[39,1586,146],{"class":86},[39,1588,1589],{"class":49},"\"r2\"",[39,1591,405],{"class":86},[39,1593,820],{"class":243},[39,1595,136],{"class":82},[39,1597,1598],{"class":49},"\"Row\"",[39,1600,944],{"class":86},[39,1602,1603,1606,1608,1610,1613,1615,1618,1620,1623,1625,1627,1629,1631,1633,1636,1638,1640,1642,1644,1646,1648,1650,1652,1654,1656,1659,1661,1663,1665],{"class":41,"line":290},[39,1604,1605],{"class":86},"                    pd.DataFrame(np.ones((",[39,1607,544],{"class":142},[39,1609,146],{"class":86},[39,1611,1612],{"class":142},"40_000",[39,1614,240],{"class":86},[39,1616,1617],{"class":243},"dtype",[39,1619,136],{"class":82},[39,1621,1622],{"class":142},"int",[39,1624,240],{"class":86},[39,1626,244],{"class":243},[39,1628,136],{"class":82},[39,1630,249],{"class":86},[39,1632,252],{"class":82},[39,1634,1635],{"class":49},"\"f",[39,1637,259],{"class":258},[39,1639,262],{"class":86},[39,1641,265],{"class":258},[39,1643,268],{"class":49},[39,1645,271],{"class":82},[39,1647,274],{"class":86},[39,1649,277],{"class":82},[39,1651,280],{"class":142},[39,1653,197],{"class":86},[39,1655,1612],{"class":142},[39,1657,1658],{"class":86},")])], ",[39,1660,1471],{"class":243},[39,1662,136],{"class":82},[39,1664,351],{"class":142},[39,1666,173],{"class":86},[39,1668,1669,1672,1674,1677,1680],{"class":41,"line":306},[39,1670,1671],{"class":86},"sheets ",[39,1673,136],{"class":82},[39,1675,1676],{"class":86}," write_wide(matrix, ",[39,1678,1679],{"class":49},"\"feature_matrix.xlsx\"",[39,1681,173],{"class":86},[39,1683,1684,1687,1690,1692,1694,1696],{"class":41,"line":332},[39,1685,1686],{"class":82},"with",[39,1688,1689],{"class":86}," pd.ExcelFile(",[39,1691,1679],{"class":49},[39,1693,1494],{"class":86},[39,1695,90],{"class":82},[39,1697,1698],{"class":86}," book:\n",[39,1700,1701,1703,1706,1709],{"class":41,"line":375},[39,1702,194],{"class":142},[39,1704,1705],{"class":86},"(sheets, ",[39,1707,1708],{"class":49},"\"sheets:\"",[39,1710,1711],{"class":86},", book.sheet_names)\n",[39,1713,1715,1717,1719,1722,1725,1727,1729,1731,1733,1735,1738,1740,1743,1746,1749,1751,1753,1755,1757],{"class":41,"line":1714},16,[39,1716,194],{"class":142},[39,1718,197],{"class":86},[39,1720,1721],{"class":142},"sum",[39,1723,1724],{"class":86},"(book.parse(s).shape[",[39,1726,351],{"class":142},[39,1728,720],{"class":86},[39,1730,400],{"class":82},[39,1732,1524],{"class":142},[39,1734,271],{"class":82},[39,1736,1737],{"class":86}," s ",[39,1739,277],{"class":82},[39,1741,1742],{"class":86}," book.sheet_names), ",[39,1744,1745],{"class":49},"\"value columns written of\"",[39,1747,1748],{"class":86},", matrix.shape[",[39,1750,351],{"class":142},[39,1752,720],{"class":86},[39,1754,400],{"class":82},[39,1756,1524],{"class":142},[39,1758,173],{"class":86},[10,1760,1761,1762,23],{},"Sometimes the wide layout is the point — a system on the other end expects it, or the reader wants to scroll across. Then split the columns into blocks of at most 16,000, and repeat the key columns at the start of every sheet so each sheet can be read on its own. Naming the sheets after the column range they hold makes it easy to find a given column. The check at the end counts the value columns across all sheets and compares with the source, the kind of reconciliation that turns \"it probably wrote everything\" into a fact. Be honest with the reader, though: 40,000 columns across three sheets is hard to use in Excel, and if the consumer is another program, CSV or Parquet is usually the better format — see ",[19,1763,1765],{"href":1764},"\u002Fgetting-started-with-python-excel-automation\u002Fchoosing-a-python-excel-library\u002Fexcel-vs-csv-vs-parquet-for-python-data-pipelines\u002F","Excel vs CSV vs Parquet for Python Data Pipelines",[25,1767,1769],{"id":1768},"why-wide-sheets-are-hard-to-use-anyway","Why wide sheets are hard to use anyway",[10,1771,1772,1773,1776,1777,1780,1781,1784],{},"Even below the limit, very wide sheets work against the way Excel is built. Sorting, filtering, tables and pivot tables all treat a ",[427,1774,1775],{},"row"," as a record and a ",[427,1778,1779],{},"column"," as a field, so data with thousands of fields per record leaves most of those tools with nothing to do. Scrolling across thousands of columns is slow, column letters such as ",[427,1782,1783],{},"AKZ"," mean nothing to a reader, frozen panes can only keep a few columns in view, and printing is out of the question. File size and opening time grow too, because every cell is stored separately whatever its shape. A useful rule of thumb is that if a sheet is wider than it is long, it is probably on its side. Choosing the shape for the reader, rather than the shape the data happened to arrive in, solves the limit and the usability problem at the same time.",[436,1786,445,1791,445,1794,445,1797,445,1800,445,1805,445,1810,445,1813,445,1817,445,1820,445,1825,445,1830,445,1833,445,1838,445,1841,445,1845,445,1848,445,1851,445,1856,445,1859,445,1863,445,1866,445,1869,445,1873,445,1876,445,1880,445,1883,445,1887,445,1890,445,1893,445,1898,445,1901,445,1904],{"viewBox":1787,"role":439,"ariaLabelledBy":1788,"xmlns":443,"style":1285},"4 0 752 126",[1789,1790],"wide-choose-t","wide-choose-d",[447,1792,1793],{"id":1789},"Choosing a fix for a wide DataFrame",[451,1795,1796],{"id":1790},"First compute the written width including the index. If it fits, write it. If not, transpose short-and-wide data, melt data that has a row key and one column per date or item, and split across sheets only when the wide layout itself is required.",[455,1798],{"x":603,"y":458,"width":1294,"height":1799,"fill":461},"126",[455,1801],{"x":1298,"y":465,"width":1802,"height":1803,"rx":1804,"fill":468,"stroke":469,"style":1302},"115.2","94.0","12",[476,1806,522],{"x":1807,"y":1808,"style":1809},"77.6","41.5","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle",[476,1811,1812],{"x":1807,"y":513,"style":1809},"width",[476,1814,1816],{"x":1807,"y":464,"style":1815},"font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","columns +",[476,1818,1819],{"x":1807,"y":571,"style":1815},"index levels",[41,1821],{"x1":1822,"y1":1823,"x2":1824,"y2":1823,"stroke":517,"style":1302},"140.2","63.0","162.2",[1826,1827],"polygon",{"points":1828,"fill":1829},"166.2,63.0 157.2,68.0 157.2,58.0","#5b5cf0",[455,1831],{"x":1832,"y":465,"width":1802,"height":1803,"rx":1804,"fill":621,"stroke":622,"style":1302},"171.2",[476,1834,1837],{"x":1835,"y":513,"style":1836},"228.8","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","≤ 16,384?",[476,1839,1840],{"x":1835,"y":464,"style":1815},"write as is",[41,1842],{"x1":1843,"y1":1823,"x2":1844,"y2":1823,"stroke":517,"style":1302},"291.4","313.4",[1826,1846],{"points":1847,"fill":1829},"317.4,63.0 308.4,68.0 308.4,58.0",[455,1849],{"x":1850,"y":465,"width":1802,"height":1803,"rx":1804,"fill":516,"stroke":517,"style":1302},"322.4",[476,1852,1855],{"x":1853,"y":513,"style":1854},"380.0","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Few rows?",[476,1857,1858],{"x":1853,"y":464,"style":1815},"transpose",[41,1860],{"x1":1861,"y1":1823,"x2":1862,"y2":1823,"stroke":517,"style":1302},"442.6","464.6",[1826,1864],{"points":1865,"fill":1829},"468.6,63.0 459.6,68.0 459.6,58.0",[455,1867],{"x":1868,"y":465,"width":1802,"height":1803,"rx":1804,"fill":516,"stroke":517,"style":1302},"473.6",[476,1870,1872],{"x":1871,"y":1808,"style":1854},"531.2","Key + one",[476,1874,1875],{"x":1871,"y":513,"style":1854},"column per",[476,1877,1879],{"x":1871,"y":1878,"style":1854},"76.5","date?",[476,1881,1882],{"x":1871,"y":571,"style":1815},"melt to long",[41,1884],{"x1":1885,"y1":1823,"x2":1886,"y2":1823,"stroke":517,"style":1302},"593.8","615.8",[1826,1888],{"points":1889,"fill":1829},"619.8,63.0 610.8,68.0 610.8,58.0",[455,1891],{"x":1892,"y":465,"width":1802,"height":1803,"rx":1804,"fill":563,"stroke":564,"style":1302},"624.8",[476,1894,1897],{"x":1895,"y":1808,"style":1896},"682.4","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Wide layout",[476,1899,1900],{"x":1895,"y":513,"style":1896},"required?",[476,1902,1903],{"x":1895,"y":464,"style":1815},"split across",[476,1905,1906],{"x":1895,"y":571,"style":1815},"sheets",[25,1908,1910],{"id":1909},"common-pitfalls","Common pitfalls",[1912,1913,1914,1922,1930,1936,1942],"ul",{},[1915,1916,1917,1921],"li",{},[1918,1919,1920],"strong",{},"Trusting pandas' check."," It ignores the index; measure the written width yourself.",[1915,1923,1924,1929],{},[1918,1925,1926,1927,23],{},"MultiIndex and ",[14,1928,433],{}," Each adds columns to the written width.",[1915,1931,1932,1935],{},[1918,1933,1934],{},"Keeping data on its side."," Short-and-wide data reads better transposed.",[1915,1937,1938,1941],{},[1918,1939,1940],{},"Daily columns for years."," Melt to long format and let pivot tables widen it.",[1915,1943,1944,1947],{},[1918,1945,1946],{},"Splitting without keys."," Repeat the key columns on every sheet so each stands alone.",[25,1949,1951],{"id":1950},"conclusion","Conclusion",[10,1953,1954,1955,1958,1959,1961],{},"Excel sheets end at 16,384 columns. pandas raises an error for DataFrames wider than that, but it does not count the index, so a frame that fits exactly loses its last column silently when written with ",[14,1956,1957],{},"index=True",". Compute the written width — columns, plus index levels, plus ",[14,1960,433],{}," — before writing, then transpose short-and-wide data, melt time series to long format, or split the columns across sheets with the key columns repeated, and count the columns written afterwards.",[25,1963,1965],{"id":1964},"frequently-asked-questions","Frequently asked questions",[10,1967,1968,1971],{},[1918,1969,1970],{},"What is the maximum number of columns in Excel?","\n16,384 per sheet, up to column XFD, with 1,048,576 rows.",[10,1973,1974,1977],{},[1918,1975,1976],{},"What does \"This sheet is too large! Your sheet size is …\" mean in pandas?","\nThe DataFrame is wider or longer than an Excel sheet allows; reshape it, split it across sheets or use another format.",[10,1979,1980,1983,1984,1986],{},[1918,1981,1982],{},"Why is the last column missing after to_excel?","\nIf the DataFrame has exactly 16,384 columns and the index is written, the index takes one column and the last data column falls beyond XFD; use ",[14,1985,895],{}," or reshape.",[10,1988,1989,1992],{},[1918,1990,1991],{},"How do I write a DataFrame with more than 16,384 columns to Excel?","\nTranspose it if it is short, melt it to long format if it has a key, or split its columns across several sheets.",[25,1994,1996],{"id":1995},"related","Related",[1912,1998,1999,2005,2012,2019],{},[1915,2000,2001,2002,2004],{},"Up one level: ",[19,2003,22],{"href":21}," — getting DataFrames into Excel.",[1915,2006,2007,2011],{},[19,2008,2010],{"href":2009},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fwrite-a-million-rows-to-excel-with-xlsxwriter-constant-memory\u002F","Write a Million Rows to Excel with XlsxWriter Constant Memory"," — the other limit.",[1915,2013,2014,2018],{},[19,2015,2017],{"href":2016},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fconvert-excel-files-to-parquet-with-python\u002F","Convert Excel Files to Parquet with Python"," — a format without the limits.",[1915,2020,2021,2023],{},[19,2022,1278],{"href":1277}," — wide to long.",[2025,2026,2027],"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 .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}",{"title":35,"searchDepth":96,"depth":96,"links":2029},[2030,2031,2032,2033,2034,2035,2036,2037,2038,2039,2040],{"id":27,"depth":96,"text":28},{"id":69,"depth":96,"text":70},{"id":654,"depth":96,"text":655},{"id":898,"depth":96,"text":899},{"id":1043,"depth":96,"text":1044},{"id":1356,"depth":96,"text":1357},{"id":1768,"depth":96,"text":1769},{"id":1909,"depth":96,"text":1910},{"id":1950,"depth":96,"text":1951},{"id":1964,"depth":96,"text":1965},{"id":1995,"depth":96,"text":1996},"2026-10-02","Excel stops at 16,384 columns. pandas raises \"This sheet is too large!\" above that — but only checks the DataFrame itself, so a frame that fits exactly loses its last column silently when the index is written. Detect the real width, then choose a fix: transpose short-and-wide data, reshape to long format with melt, or split the columns across several sheets with the key repeated on each, and check what was written.","md",[2045,2047,2049,2051],{"q":1970,"a":2046},"16,384 per sheet, up to column XFD, with 1,048,576 rows.",{"q":1976,"a":2048},"The DataFrame is wider or longer than an Excel sheet allows; reshape it, split it across sheets or use another format.",{"q":1982,"a":2050},"If the DataFrame has exactly 16,384 columns and the index is written, the index takes one column and the last data column falls beyond XFD; use index=False or reshape.",{"q":1991,"a":2052},"Transpose it if it is short, melt it to long format if it has a key, or split its columns across several sheets.","dataframe too many columns excel",null,{"breadcrumb":2056},[2057,2060,2063],{"name":2058,"item":2059},"Home","\u002F",{"name":2061,"item":2062},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":2064,"item":21},"Writing DataFrames to Excel with Pandas","\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-very-wide-dataframes-to-excel",{"title":2067,"description":2068},"Write Very Wide DataFrames to Excel with pandas","Write DataFrames wider than Excel allows: the 16,384-column limit, the too-large error, the silent lost column when the index is written, transposing, melting to long format and splitting across sheets.","write-very-wide-dataframes-to-excel","getting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-very-wide-dataframes-to-excel\u002Findex",[2072,2073],"writing-excel","troubleshooting","how-to","od44ZC-gMhELaJUiVS78Mgh-1PfrSyRvqW9BhOrot_g",[2077,2054],{"title":2078,"path":2079,"stem":2080,"children":-1},"Write a Pandas DataFrame to Excel Without the Index","\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-pandas-dataframe-to-excel-without-index","getting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-pandas-dataframe-to-excel-without-index\u002Findex",[2082,2084],{"path":2083,"title":2061},"\u002Fgetting-started-with-python-excel-automation",{"path":2085,"title":2064},"\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas",[],[2088,2091,2094,2097,2100,2103],{"path":2089,"title":2090,"kind":2074},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fwrite-multiple-dataframes-to-one-excel-file","Write Multiple DataFrames to One Excel File",{"path":2092,"title":2093,"kind":2074},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fwrite-a-formatted-excel-report-with-xlsxwriter","Write a Formatted Excel Report with xlsxwriter",{"path":2095,"title":2096,"kind":2074},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Ffind-and-replace-text-in-excel-with-openpyxl","Find and Replace Text in Excel with openpyxl",{"path":2098,"title":2099,"kind":2074},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Finsert-and-delete-rows-and-columns-with-openpyxl","Insert and Delete Rows and Columns with openpyxl",{"path":2101,"title":2102,"kind":2074},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fopenpyxl-append-data-to-existing-excel-sheet","openpyxl: Append Data to an Existing Excel Sheet",{"path":2104,"title":2105,"kind":2074},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Freorder-columns-to-match-a-template-layout-with-pandas","Reorder Columns to Match a Template Layout with pandas",1790972077979]