[{"data":1,"prerenderedAt":1833},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freturn-dataframes-and-values-from-python-in-excel-cells":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freturn-dataframes-and-values-from-python-in-excel-cells":1800,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freturn-dataframes-and-values-from-python-in-excel-cells":1808,"children:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freturn-dataframes-and-values-from-python-in-excel-cells":1813,"related:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freturn-dataframes-and-values-from-python-in-excel-cells":1814},{"id":4,"title":5,"body":6,"dateModified":1767,"datePublished":1767,"description":1768,"extension":1769,"faq":1770,"keyword":1779,"kind":1780,"meta":1781,"navigation":537,"path":1790,"seo":1791,"slug":1793,"stem":1794,"topics":1795,"type":1798,"__hash__":1799},"docs\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freturn-dataframes-and-values-from-python-in-excel-cells\u002Findex.md","Return DataFrames and Values from Python in Excel Cells",{"type":7,"value":8,"toc":1752},"minimark",[9,41,152,157,191,195,207,293,303,306,310,321,338,425,434,501,505,508,703,713,717,720,799,810,1036,1040,1043,1158,1165,1169,1172,1310,1313,1317,1324,1548,1551,1555,1656,1660,1667,1671,1682,1686,1692,1698,1704,1710,1714,1748],[10,11,12,13,17,18,21,22,26,27,30,31,36,37,40],"p",{},"Getting data ",[14,15,16],"em",{},"into"," a Python in Excel formula is one function call. Getting a useful result ",[14,19,20],{},"out"," is where\nmost of the confusion lives: a cell that shows a little card reading ",[23,24,25],"code",{},"DataFrame"," instead of numbers, a\nresult that spills over data somebody typed next to it, a column of dates that turns into five-digit\nnumbers, or a formula that returns ",[23,28,29],{},"None"," because its last line was an assignment. This guide, part of\n",[32,33,35],"a",{"href":34},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002F","Using Python in Excel",", explains\nhow a ",[23,38,39],{},"=PY"," cell decides what to return and how to shape the result so it lands in the grid the way you\nintended.",[42,43,51,52,51,56,51,60,51,67,51,77,51,83,51,88,51,92,51,95,51,100,51,105,51,110,51,114,51,119,51,123,51,125,51,128,51,133,51,137,51,141,51,144,51,147],"svg",{"viewBox":44,"role":45,"ariaLabelledBy":46,"xmlns":49,"style":50},"0 0 760 282","img",[47,48],"ret-modes-t","ret-modes-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:760px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[53,54,55],"title",{"id":47},"The two output types of a Python formula",[57,58,59],"desc",{"id":48},"The last expression of a Python cell is returned either as a Python object, shown as a card and reusable by later Python cells, or as Excel values, converted and spilled into the grid where Excel formulas and charts can use them.",[61,62],"rect",{"x":63,"y":63,"width":64,"height":65,"fill":66},"0","760","282","#ffffff",[61,68],{"x":69,"y":70,"width":71,"height":72,"rx":73,"fill":74,"stroke":75,"style":76},"200","20","360","52","12","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:2px",[78,79,82],"text",{"x":80,"y":72,"style":81},"380","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","last expression of the =PY cell",[84,85],"line",{"x1":80,"y1":86,"x2":80,"y2":87,"stroke":75,"style":76},"72","100",[84,89],{"x1":90,"y1":87,"x2":91,"y2":87,"stroke":75,"style":76},"195","565",[84,93],{"x1":90,"y1":87,"x2":90,"y2":94,"stroke":75,"style":76},"124",[96,97],"polygon",{"points":98,"fill":99},"195,127 190,118 200,118","#5b5cf0",[61,101],{"x":70,"y":102,"width":103,"height":104,"rx":73,"fill":74,"stroke":75,"style":76},"128","350","104",[78,106,109],{"x":90,"y":107,"style":108},"150","font-size:11px;font-weight:600;fill:var(--brand-strong,#4338ca);text-anchor:middle","output: Python object",[78,111,113],{"x":90,"y":112,"style":81},"174","card in the cell",[78,115,118],{"x":90,"y":116,"style":117},"196","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","kept as a live object",[78,120,122],{"x":90,"y":121,"style":117},"216","reused by later cells",[84,124],{"x1":91,"y1":87,"x2":91,"y2":94,"stroke":75,"style":76},[96,126],{"points":127,"fill":99},"565,127 560,118 570,118",[61,129],{"x":130,"y":102,"width":103,"height":104,"rx":73,"fill":131,"stroke":132,"style":76},"390","#d9f4f1","var(--teal,#0f9488)",[78,134,136],{"x":91,"y":107,"style":135},"font-size:11px;font-weight:600;fill:var(--teal-ink,#0b6157);text-anchor:middle","output: Excel value",[78,138,140],{"x":91,"y":112,"style":139},"font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","spilled values",[78,142,143],{"x":91,"y":116,"style":117},"converted for the grid",[78,145,146],{"x":91,"y":121,"style":117},"charts and formulas",[78,148,151],{"x":80,"y":149,"style":150},"266","font-size:12.5px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle","toggle between them with Ctrl+Alt+Shift+M",[153,154,156],"h2",{"id":155},"prerequisites","Prerequisites",[158,159,160,164],"ul",{},[161,162,163],"li",{},"Excel with Python in Excel available and enabled.",[161,165,166,167,170,171,174,175,174,178,181,182,185,186,190],{},"A table named ",[23,168,169],{},"Sales"," with ",[23,172,173],{},"Date",", ",[23,176,177],{},"Region",[23,179,180],{},"Rep"," and ",[23,183,184],{},"Amount"," columns, referenced as in\n",[32,187,189],{"href":188},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel\u002F","Reference Cells, Ranges and Tables with xl() in Python in Excel",".",[153,192,194],{"id":193},"step-1-understand-the-last-expression-rule","Step 1 — Understand the last-expression rule",[10,196,197,198,201,202,206],{},"A Python formula has no ",[23,199,200],{},"return"," statement. Like a notebook cell, it returns the value of its ",[203,204,205],"strong",{},"last\nexpression",". Everything before that line runs for its side effects — variable assignments, imports, helper\nfunctions — and only the final expression reaches the cell.",[208,209,214],"pre",{"className":210,"code":211,"language":212,"meta":213,"style":213},"language-python shiki shiki-themes github-light github-dark-high-contrast","sales = xl(\"Sales[#All]\", headers=True)\nby_region = sales.groupby(\"Region\", as_index=False)[\"Amount\"].sum()\nby_region                     # the last expression: this is what the cell returns\n","python","",[23,215,216,250,283],{"__ignoreMap":213},[217,218,220,224,228,231,235,237,241,243,247],"span",{"class":84,"line":219},1,[217,221,223],{"class":222},"skGVy","sales ",[217,225,227],{"class":226},"s-kum","=",[217,229,230],{"class":222}," xl(",[217,232,234],{"class":233},"srMev","\"Sales[#All]\"",[217,236,174],{"class":222},[217,238,240],{"class":239},"sa561","headers",[217,242,227],{"class":226},[217,244,246],{"class":245},"sP0c6","True",[217,248,249],{"class":222},")\n",[217,251,253,256,258,261,264,266,269,271,274,277,280],{"class":84,"line":252},2,[217,254,255],{"class":222},"by_region ",[217,257,227],{"class":226},[217,259,260],{"class":222}," sales.groupby(",[217,262,263],{"class":233},"\"Region\"",[217,265,174],{"class":222},[217,267,268],{"class":239},"as_index",[217,270,227],{"class":226},[217,272,273],{"class":245},"False",[217,275,276],{"class":222},")[",[217,278,279],{"class":233},"\"Amount\"",[217,281,282],{"class":222},"].sum()\n",[217,284,286,289],{"class":84,"line":285},3,[217,287,288],{"class":222},"by_region                     ",[217,290,292],{"class":291},"s-wDw","# the last expression: this is what the cell returns\n",[10,294,295,296,299,300,302],{},"End a formula with an assignment such as ",[23,297,298],{},"by_region = …"," and there is no expression to return, so the cell\nshows ",[23,301,29],{},". It is the most common \"my formula does nothing\" report, and the fix is always to repeat the\nvariable name on its own line.",[10,304,305],{},"Variables assigned in one Python cell remain available to Python cells that calculate after it. That is what\nmakes it practical to load and clean a table once near the top of the sheet and derive several small outputs\nfrom it further down.",[153,307,309],{"id":308},"step-2-choose-python-object-or-excel-value","Step 2 — Choose Python object or Excel value",[10,311,312,313,316,317,320],{},"Every Python formula has an output type, set from the ",[203,314,315],{},"Python output"," menu next to the formula bar, from the\ncell's right-click menu, or with ",[203,318,319],{},"Ctrl+Alt+Shift+M",":",[158,322,323,332],{},[161,324,325,328,329,331],{},[203,326,327],{},"Python object"," keeps the result as a live Python value. A DataFrame shows as a card with a ",[23,330,25],{},"\nlabel; you can open the card to preview it. Nothing is written into neighbouring cells.",[161,333,334,337],{},[203,335,336],{},"Excel value"," converts the result to the closest Excel equivalent. A scalar becomes an ordinary number,\ntext or date; a DataFrame or Series spills across the cells below and to the right.",[208,339,341],{"className":210,"code":340,"language":212,"meta":213,"style":213},"sales = xl(\"Sales[#All]\", headers=True)\npivot = sales.pivot_table(index=\"Rep\", columns=\"Region\", values=\"Amount\", aggfunc=\"sum\", fill_value=0)\npivot\n",[23,342,343,363,420],{"__ignoreMap":213},[217,344,345,347,349,351,353,355,357,359,361],{"class":84,"line":219},[217,346,223],{"class":222},[217,348,227],{"class":226},[217,350,230],{"class":222},[217,352,234],{"class":233},[217,354,174],{"class":222},[217,356,240],{"class":239},[217,358,227],{"class":226},[217,360,246],{"class":245},[217,362,249],{"class":222},[217,364,365,368,370,373,376,378,381,383,386,388,390,392,395,397,399,401,404,406,409,411,414,416,418],{"class":84,"line":252},[217,366,367],{"class":222},"pivot ",[217,369,227],{"class":226},[217,371,372],{"class":222}," sales.pivot_table(",[217,374,375],{"class":239},"index",[217,377,227],{"class":226},[217,379,380],{"class":233},"\"Rep\"",[217,382,174],{"class":222},[217,384,385],{"class":239},"columns",[217,387,227],{"class":226},[217,389,263],{"class":233},[217,391,174],{"class":222},[217,393,394],{"class":239},"values",[217,396,227],{"class":226},[217,398,279],{"class":233},[217,400,174],{"class":222},[217,402,403],{"class":239},"aggfunc",[217,405,227],{"class":226},[217,407,408],{"class":233},"\"sum\"",[217,410,174],{"class":222},[217,412,413],{"class":239},"fill_value",[217,415,227],{"class":226},[217,417,63],{"class":245},[217,419,249],{"class":222},[217,421,422],{"class":84,"line":285},[217,423,424],{"class":222},"pivot\n",[10,426,427,428,430,431,433],{},"Leave a formula like this one as a ",[203,429,327],{}," while you are still building the workbook, so an\nintermediate result does not overwrite anything. Switch it to ",[203,432,336],{}," once you want other people — or\nExcel charts, conditional formats and ordinary formulas — to see the numbers.",[42,435,51,440,51,443,51,446,51,449,51,452,51,456,51,462,51,466,51,470,51,473,51,477,51,479,51,482,51,486,51,489,51,492,51,495,51,498],{"viewBox":436,"role":45,"ariaLabelledBy":437,"xmlns":49,"style":50},"0 0 760 214",[438,439],"ret-compare-t","ret-compare-d",[53,441,442],{"id":438},"Python object versus Excel value, side by side",[57,444,445],{"id":439},"A Python object occupies one cell, previews as a card and can be reused by later Python cells. An Excel value spills into a block of cells, can feed charts and formulas, but can collide with existing data.",[61,447],{"x":63,"y":63,"width":64,"height":448,"fill":66},"214",[61,450],{"x":70,"y":70,"width":103,"height":107,"rx":451,"fill":74,"stroke":75,"style":76},"14",[78,453,327],{"x":90,"y":454,"style":455},"46","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle",[84,457],{"x1":458,"y1":459,"x2":460,"y2":459,"stroke":75,"style":461},"36","56","354","stroke-width:1px",[78,463,465],{"x":90,"y":464,"style":117},"78","one cell, shown as a card",[78,467,469],{"x":90,"y":468,"style":117},"101","keeps pandas types",[78,471,472],{"x":90,"y":94,"style":117},"reusable in later =PY cells",[78,474,476],{"x":90,"y":475,"style":117},"147","invisible to Excel formulas",[61,478],{"x":130,"y":70,"width":103,"height":107,"rx":451,"fill":131,"stroke":132,"style":76},[78,480,336],{"x":91,"y":454,"style":481},"font-size:13px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle",[84,483],{"x1":484,"y1":459,"x2":485,"y2":459,"stroke":132,"style":461},"406","724",[78,487,488],{"x":91,"y":464,"style":117},"spills into a block of cells",[78,490,491],{"x":91,"y":468,"style":117},"converted to Excel types",[78,493,494],{"x":91,"y":94,"style":117},"feeds charts and formulas",[78,496,497],{"x":91,"y":475,"style":117},"needs empty cells: #SPILL!",[78,499,500],{"x":80,"y":69,"style":150},"build with objects, publish with values",[153,502,504],{"id":503},"step-3-shape-a-dataframe-before-it-spills","Step 3 — Shape a DataFrame before it spills",[10,506,507],{},"When a DataFrame is converted to Excel values, what you see is exactly what the frame holds — including its\nindex, its full-precision floats and its internal column names. Tidy those in Python rather than fixing them in\nthe grid afterwards, because the spill is regenerated on every recalculation and manual edits to it are not\npossible.",[208,509,511],{"className":210,"code":510,"language":212,"meta":213,"style":213},"sales = xl(\"Sales[#All]\", headers=True)\n\nreport = (\n    sales.groupby([\"Region\", \"Rep\"])[\"Amount\"]\n         .agg(Total=\"sum\", Deals=\"count\", Average=\"mean\")\n         .round({\"Total\": 0, \"Average\": 2})\n         .sort_values(\"Total\", ascending=False)\n         .reset_index()                       # index levels become ordinary columns\n         .rename(columns={\"Rep\": \"Sales rep\"})\n         .head(10)\n)\nreport\n",[23,512,513,533,539,549,569,604,631,650,659,681,692,697],{"__ignoreMap":213},[217,514,515,517,519,521,523,525,527,529,531],{"class":84,"line":219},[217,516,223],{"class":222},[217,518,227],{"class":226},[217,520,230],{"class":222},[217,522,234],{"class":233},[217,524,174],{"class":222},[217,526,240],{"class":239},[217,528,227],{"class":226},[217,530,246],{"class":245},[217,532,249],{"class":222},[217,534,535],{"class":84,"line":252},[217,536,538],{"emptyLinePlaceholder":537},true,"\n",[217,540,541,544,546],{"class":84,"line":285},[217,542,543],{"class":222},"report ",[217,545,227],{"class":226},[217,547,548],{"class":222}," (\n",[217,550,552,555,557,559,561,564,566],{"class":84,"line":551},4,[217,553,554],{"class":222},"    sales.groupby([",[217,556,263],{"class":233},[217,558,174],{"class":222},[217,560,380],{"class":233},[217,562,563],{"class":222},"])[",[217,565,279],{"class":233},[217,567,568],{"class":222},"]\n",[217,570,572,575,578,580,582,584,587,589,592,594,597,599,602],{"class":84,"line":571},5,[217,573,574],{"class":222},"         .agg(",[217,576,577],{"class":239},"Total",[217,579,227],{"class":226},[217,581,408],{"class":233},[217,583,174],{"class":222},[217,585,586],{"class":239},"Deals",[217,588,227],{"class":226},[217,590,591],{"class":233},"\"count\"",[217,593,174],{"class":222},[217,595,596],{"class":239},"Average",[217,598,227],{"class":226},[217,600,601],{"class":233},"\"mean\"",[217,603,249],{"class":222},[217,605,607,610,613,616,618,620,623,625,628],{"class":84,"line":606},6,[217,608,609],{"class":222},"         .round({",[217,611,612],{"class":233},"\"Total\"",[217,614,615],{"class":222},": ",[217,617,63],{"class":245},[217,619,174],{"class":222},[217,621,622],{"class":233},"\"Average\"",[217,624,615],{"class":222},[217,626,627],{"class":245},"2",[217,629,630],{"class":222},"})\n",[217,632,634,637,639,641,644,646,648],{"class":84,"line":633},7,[217,635,636],{"class":222},"         .sort_values(",[217,638,612],{"class":233},[217,640,174],{"class":222},[217,642,643],{"class":239},"ascending",[217,645,227],{"class":226},[217,647,273],{"class":245},[217,649,249],{"class":222},[217,651,653,656],{"class":84,"line":652},8,[217,654,655],{"class":222},"         .reset_index()                       ",[217,657,658],{"class":291},"# index levels become ordinary columns\n",[217,660,662,665,667,669,672,674,676,679],{"class":84,"line":661},9,[217,663,664],{"class":222},"         .rename(",[217,666,385],{"class":239},[217,668,227],{"class":226},[217,670,671],{"class":222},"{",[217,673,380],{"class":233},[217,675,615],{"class":222},[217,677,678],{"class":233},"\"Sales rep\"",[217,680,630],{"class":222},[217,682,684,687,690],{"class":84,"line":683},10,[217,685,686],{"class":222},"         .head(",[217,688,689],{"class":245},"10",[217,691,249],{"class":222},[217,693,695],{"class":84,"line":694},11,[217,696,249],{"class":222},[217,698,700],{"class":84,"line":699},12,[217,701,702],{"class":222},"report\n",[10,704,705,708,709,712],{},[23,706,707],{},"reset_index()"," is the step that matters most. A grouped result keeps its group keys in the index, and turning\nthem into regular columns gives you control over their names and position in the spilled block. ",[23,710,711],{},"head(10)","\nkeeps the spill a predictable size, which is the easiest way to leave room for content underneath.",[153,714,716],{"id":715},"step-4-return-single-values-for-kpis-and-labels","Step 4 — Return single values for KPIs and labels",[10,718,719],{},"Not every formula should spill. A headline number that an Excel chart title, a text box or a conditional format\nrefers to is best returned as a scalar, converted to an Excel value so it behaves like any other number.",[208,721,723],{"className":210,"code":722,"language":212,"meta":213,"style":213},"sales = xl(\"Sales[#All]\", headers=True)\nthis_month = sales[sales[\"Date\"] >= sales[\"Date\"].max().replace(day=1)]\nfloat(this_month[\"Amount\"].sum())            # a plain number in the cell\n",[23,724,725,745,783],{"__ignoreMap":213},[217,726,727,729,731,733,735,737,739,741,743],{"class":84,"line":219},[217,728,223],{"class":222},[217,730,227],{"class":226},[217,732,230],{"class":222},[217,734,234],{"class":233},[217,736,174],{"class":222},[217,738,240],{"class":239},[217,740,227],{"class":226},[217,742,246],{"class":245},[217,744,249],{"class":222},[217,746,747,750,752,755,758,761,764,767,769,772,775,777,780],{"class":84,"line":252},[217,748,749],{"class":222},"this_month ",[217,751,227],{"class":226},[217,753,754],{"class":222}," sales[sales[",[217,756,757],{"class":233},"\"Date\"",[217,759,760],{"class":222},"] ",[217,762,763],{"class":226},">=",[217,765,766],{"class":222}," sales[",[217,768,757],{"class":233},[217,770,771],{"class":222},"].max().replace(",[217,773,774],{"class":239},"day",[217,776,227],{"class":226},[217,778,779],{"class":245},"1",[217,781,782],{"class":222},")]\n",[217,784,785,788,791,793,796],{"class":84,"line":285},[217,786,787],{"class":245},"float",[217,789,790],{"class":222},"(this_month[",[217,792,279],{"class":233},[217,794,795],{"class":222},"].sum())            ",[217,797,798],{"class":291},"# a plain number in the cell\n",[10,800,801,802,805,806,809],{},"The ",[23,803,804],{},"float()"," call is deliberate. pandas aggregations return NumPy scalar types, which convert fine, but an\nexplicit Python number makes the intent obvious and guards against returning a one-element Series by accident.\nFor a label, return a formatted string — ",[23,807,808],{},"f\"{total:,.0f} this month\""," — and accept that the cell then holds text\nrather than a number that other formulas can use.",[42,811,51,817,51,820,51,823,51,827,51,832,51,835,51,841,51,845,51,849,51,853,51,857,51,860,51,864,51,867,51,871,51,873,51,877,51,879,51,883,51,885,51,887,51,892,51,897,51,900,51,902,51,904,51,906,51,908,51,910,51,912,51,916,51,918,51,920,51,922,51,925,51,927,51,929,51,931,51,933,51,936,51,940,51,943,51,947,51,949,51,952,51,954,51,957,51,959,51,962,51,964,51,967,51,970,51,974,51,976,51,979,51,981,51,984,51,986,51,989,51,991,51,994,51,996,51,999,51,1001,51,1004,51,1006,51,1008,51,1010,51,1013,51,1016,51,1018,51,1020,51,1022,51,1024,51,1027,51,1031],{"viewBox":812,"role":45,"ariaLabelledBy":813,"xmlns":49,"style":816},"0 0 668 314",[814,815],"ret-layout-t","ret-layout-d","width:100%;max-width:668px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[53,818,819],{"id":814},"A sheet layout that leaves room for spilled results",[57,821,822],{"id":815},"Cell A1 holds a Python object with the cleaned sales data, B1 holds a single KPI value, and A3 spills a ten-row report block with free cells underneath and to the right.",[61,824],{"x":63,"y":63,"width":825,"height":826,"fill":66},"668","314",[61,828],{"x":70,"y":70,"width":458,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},"30","#e7ebef","var(--line,#cdd5e6)",[61,833],{"x":459,"y":70,"width":834,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},"132",[78,836,840],{"x":837,"y":838,"style":839},"122","40","font-size:11.5px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[61,842],{"x":843,"y":70,"width":844,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},"188","110",[78,846,848],{"x":847,"y":838,"style":839},"243","B",[61,850],{"x":851,"y":70,"width":852,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},"298","90",[78,854,856],{"x":855,"y":838,"style":839},"343","C",[61,858],{"x":859,"y":70,"width":852,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},"388",[78,861,863],{"x":862,"y":838,"style":839},"433","D",[61,865],{"x":70,"y":866,"width":458,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},"50",[78,868,779],{"x":869,"y":870,"style":839},"38","70",[61,872],{"x":459,"y":866,"width":834,"height":829,"rx":63,"fill":74,"stroke":75,"style":461},[78,874,876],{"x":837,"y":870,"style":875},"font-size:11.5px;font-weight:600;fill:var(--brand-strong,#4338ca);text-anchor:middle","[DataFrame] sales",[61,878],{"x":843,"y":866,"width":844,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,880,882],{"x":847,"y":870,"style":881},"font-size:11.5px;font-weight:600;fill:var(--teal-ink,#0b6157);text-anchor:middle","48,210",[61,884],{"x":851,"y":866,"width":852,"height":829,"rx":63,"fill":66,"stroke":831,"style":461},[61,886],{"x":859,"y":866,"width":852,"height":829,"rx":63,"fill":66,"stroke":831,"style":461},[61,888],{"x":889,"y":72,"width":107,"height":890,"rx":891,"fill":74,"stroke":75,"style":461},"498","26","8",[78,893,896],{"x":894,"y":895,"style":875},"573","69","object + KPI value",[61,898],{"x":70,"y":899,"width":458,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},"80",[78,901,627],{"x":869,"y":87,"style":839},[61,903],{"x":459,"y":899,"width":834,"height":829,"rx":63,"fill":66,"stroke":831,"style":461},[61,905],{"x":843,"y":899,"width":844,"height":829,"rx":63,"fill":66,"stroke":831,"style":461},[61,907],{"x":851,"y":899,"width":852,"height":829,"rx":63,"fill":66,"stroke":831,"style":461},[61,909],{"x":859,"y":899,"width":852,"height":829,"rx":63,"fill":66,"stroke":831,"style":461},[61,911],{"x":70,"y":844,"width":458,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},[78,913,915],{"x":869,"y":914,"style":839},"130","3",[61,917],{"x":459,"y":844,"width":834,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,919,177],{"x":837,"y":914,"style":881},[61,921],{"x":843,"y":844,"width":844,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,923,924],{"x":847,"y":914,"style":881},"Sales rep",[61,926],{"x":851,"y":844,"width":852,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,928,577],{"x":855,"y":914,"style":881},[61,930],{"x":859,"y":844,"width":852,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,932,586],{"x":862,"y":914,"style":881},[61,934],{"x":889,"y":935,"width":107,"height":890,"rx":891,"fill":131,"stroke":132,"style":461},"112",[78,937,939],{"x":894,"y":938,"style":881},"129","spill from A3",[61,941],{"x":70,"y":942,"width":458,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},"140",[78,944,946],{"x":869,"y":945,"style":839},"160","4",[61,948],{"x":459,"y":942,"width":834,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,950,951],{"x":837,"y":945,"style":881},"North",[61,953],{"x":843,"y":942,"width":844,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,955,956],{"x":847,"y":945,"style":881},"Ana",[61,958],{"x":851,"y":942,"width":852,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,960,961],{"x":855,"y":945,"style":881},"9,840",[61,963],{"x":859,"y":942,"width":852,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,965,966],{"x":862,"y":945,"style":881},"7",[61,968],{"x":70,"y":969,"width":458,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},"170",[78,971,973],{"x":869,"y":972,"style":839},"190","5",[61,975],{"x":459,"y":969,"width":834,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,977,978],{"x":837,"y":972,"style":881},"South",[61,980],{"x":843,"y":969,"width":844,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,982,983],{"x":847,"y":972,"style":881},"Dev",[61,985],{"x":851,"y":969,"width":852,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,987,988],{"x":855,"y":972,"style":881},"8,120",[61,990],{"x":859,"y":969,"width":852,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,992,993],{"x":862,"y":972,"style":881},"6",[61,995],{"x":70,"y":69,"width":458,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},[78,997,993],{"x":869,"y":998,"style":839},"220",[61,1000],{"x":459,"y":69,"width":834,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[78,1002,1003],{"x":837,"y":998,"style":881},"… 8 more",[61,1005],{"x":843,"y":69,"width":844,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[61,1007],{"x":851,"y":69,"width":852,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[61,1009],{"x":859,"y":69,"width":852,"height":829,"rx":63,"fill":131,"stroke":132,"style":461},[61,1011],{"x":70,"y":1012,"width":458,"height":829,"rx":63,"fill":830,"stroke":831,"style":461},"230",[78,1014,966],{"x":869,"y":1015,"style":839},"250",[61,1017],{"x":459,"y":1012,"width":834,"height":829,"rx":63,"fill":66,"stroke":831,"style":461},[61,1019],{"x":843,"y":1012,"width":844,"height":829,"rx":63,"fill":66,"stroke":831,"style":461},[61,1021],{"x":851,"y":1012,"width":852,"height":829,"rx":63,"fill":66,"stroke":831,"style":461},[61,1023],{"x":859,"y":1012,"width":852,"height":829,"rx":63,"fill":66,"stroke":831,"style":461},[61,1025],{"x":889,"y":1026,"width":107,"height":890,"rx":891,"fill":830,"stroke":831,"style":461},"232",[78,1028,1030],{"x":894,"y":1029,"style":839},"249","kept empty",[78,1032,1035],{"x":1033,"y":1034,"style":150},"334","292","objects stay in one cell; values need a clear block",[153,1037,1039],{"id":1038},"step-5-keep-dates-and-numbers-usable","Step 5 — Keep dates and numbers usable",[10,1041,1042],{},"A spilled block contains values but no number formatting, so dates can appear as serial numbers and currency as\nraw floats. There are two approaches, and they suit different purposes.",[208,1044,1046],{"className":210,"code":1045,"language":212,"meta":213,"style":213},"sales = xl(\"Sales[#All]\", headers=True)\nmonthly = (\n    sales.set_index(\"Date\")[\"Amount\"]\n         .resample(\"MS\").sum()\n         .reset_index()\n         .rename(columns={\"Date\": \"Month\"})\n)\n\n# Option A: keep real dates and numbers; format the spill range in Excel\nmonthly\n\n# Option B: presentation-only text columns (not usable in further calculations)\n# monthly.assign(Month=monthly[\"Month\"].dt.strftime(\"%b %Y\"), Amount=monthly[\"Amount\"].map(\"{:,.0f}\".format))\n",[23,1047,1048,1068,1077,1090,1101,1106,1125,1129,1133,1138,1143,1147,1152],{"__ignoreMap":213},[217,1049,1050,1052,1054,1056,1058,1060,1062,1064,1066],{"class":84,"line":219},[217,1051,223],{"class":222},[217,1053,227],{"class":226},[217,1055,230],{"class":222},[217,1057,234],{"class":233},[217,1059,174],{"class":222},[217,1061,240],{"class":239},[217,1063,227],{"class":226},[217,1065,246],{"class":245},[217,1067,249],{"class":222},[217,1069,1070,1073,1075],{"class":84,"line":252},[217,1071,1072],{"class":222},"monthly ",[217,1074,227],{"class":226},[217,1076,548],{"class":222},[217,1078,1079,1082,1084,1086,1088],{"class":84,"line":285},[217,1080,1081],{"class":222},"    sales.set_index(",[217,1083,757],{"class":233},[217,1085,276],{"class":222},[217,1087,279],{"class":233},[217,1089,568],{"class":222},[217,1091,1092,1095,1098],{"class":84,"line":551},[217,1093,1094],{"class":222},"         .resample(",[217,1096,1097],{"class":233},"\"MS\"",[217,1099,1100],{"class":222},").sum()\n",[217,1102,1103],{"class":84,"line":571},[217,1104,1105],{"class":222},"         .reset_index()\n",[217,1107,1108,1110,1112,1114,1116,1118,1120,1123],{"class":84,"line":606},[217,1109,664],{"class":222},[217,1111,385],{"class":239},[217,1113,227],{"class":226},[217,1115,671],{"class":222},[217,1117,757],{"class":233},[217,1119,615],{"class":222},[217,1121,1122],{"class":233},"\"Month\"",[217,1124,630],{"class":222},[217,1126,1127],{"class":84,"line":633},[217,1128,249],{"class":222},[217,1130,1131],{"class":84,"line":652},[217,1132,538],{"emptyLinePlaceholder":537},[217,1134,1135],{"class":84,"line":661},[217,1136,1137],{"class":291},"# Option A: keep real dates and numbers; format the spill range in Excel\n",[217,1139,1140],{"class":84,"line":683},[217,1141,1142],{"class":222},"monthly\n",[217,1144,1145],{"class":84,"line":694},[217,1146,538],{"emptyLinePlaceholder":537},[217,1148,1149],{"class":84,"line":699},[217,1150,1151],{"class":291},"# Option B: presentation-only text columns (not usable in further calculations)\n",[217,1153,1155],{"class":84,"line":1154},13,[217,1156,1157],{"class":291},"# monthly.assign(Month=monthly[\"Month\"].dt.strftime(\"%b %Y\"), Amount=monthly[\"Amount\"].map(\"{:,.0f}\".format))\n",[10,1159,1160,1161,190],{},"Prefer option A whenever the output feeds a chart or other formulas: select the spill area in the grid and apply\na date or currency format once. Formatting applied to cells is kept when the formula recalculates. Option B is\nfor a block that is purely for reading, where the exact appearance matters more than the ability to calculate on\nit. The same trade-off exists for scripts writing files, described in\n",[32,1162,1164],{"href":1163},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002F","Applying Number and Date Formats in Excel",[153,1166,1168],{"id":1167},"step-6-chain-cells-instead-of-recomputing","Step 6 — Chain cells instead of recomputing",[10,1170,1171],{},"Because variables flow forward, a sensible workbook structure is one \"load\" cell that returns a Python object and\nseveral small \"output\" cells that each return one view as Excel values. The expensive work happens once, and each\noutput can be switched, moved or deleted independently.",[208,1173,1175],{"className":210,"code":1174,"language":212,"meta":213,"style":213},"# Cell A1 — Python object: the cleaned source, computed once\nsales = xl(\"Sales[#All]\", headers=True)\nsales = sales.dropna(subset=[\"Amount\"]).assign(Month=lambda d: d[\"Date\"].dt.to_period(\"M\").astype(str))\nsales\n\n# Cell A3 — Excel value: a view that reuses the variable from A1\nsales.pivot_table(index=\"Month\", columns=\"Region\", values=\"Amount\", aggfunc=\"sum\", fill_value=0).reset_index()\n",[23,1176,1177,1182,1202,1250,1255,1259,1264],{"__ignoreMap":213},[217,1178,1179],{"class":84,"line":219},[217,1180,1181],{"class":291},"# Cell A1 — Python object: the cleaned source, computed once\n",[217,1183,1184,1186,1188,1190,1192,1194,1196,1198,1200],{"class":84,"line":252},[217,1185,223],{"class":222},[217,1187,227],{"class":226},[217,1189,230],{"class":222},[217,1191,234],{"class":233},[217,1193,174],{"class":222},[217,1195,240],{"class":239},[217,1197,227],{"class":226},[217,1199,246],{"class":245},[217,1201,249],{"class":222},[217,1203,1204,1206,1208,1211,1214,1216,1219,1221,1224,1227,1230,1233,1235,1238,1241,1244,1247],{"class":84,"line":285},[217,1205,223],{"class":222},[217,1207,227],{"class":226},[217,1209,1210],{"class":222}," sales.dropna(",[217,1212,1213],{"class":239},"subset",[217,1215,227],{"class":226},[217,1217,1218],{"class":222},"[",[217,1220,279],{"class":233},[217,1222,1223],{"class":222},"]).assign(",[217,1225,1226],{"class":239},"Month",[217,1228,1229],{"class":226},"=lambda",[217,1231,1232],{"class":222}," d: d[",[217,1234,757],{"class":233},[217,1236,1237],{"class":222},"].dt.to_period(",[217,1239,1240],{"class":233},"\"M\"",[217,1242,1243],{"class":222},").astype(",[217,1245,1246],{"class":245},"str",[217,1248,1249],{"class":222},"))\n",[217,1251,1252],{"class":84,"line":551},[217,1253,1254],{"class":222},"sales\n",[217,1256,1257],{"class":84,"line":571},[217,1258,538],{"emptyLinePlaceholder":537},[217,1260,1261],{"class":84,"line":606},[217,1262,1263],{"class":291},"# Cell A3 — Excel value: a view that reuses the variable from A1\n",[217,1265,1266,1269,1271,1273,1275,1277,1279,1281,1283,1285,1287,1289,1291,1293,1295,1297,1299,1301,1303,1305,1307],{"class":84,"line":633},[217,1267,1268],{"class":222},"sales.pivot_table(",[217,1270,375],{"class":239},[217,1272,227],{"class":226},[217,1274,1122],{"class":233},[217,1276,174],{"class":222},[217,1278,385],{"class":239},[217,1280,227],{"class":226},[217,1282,263],{"class":233},[217,1284,174],{"class":222},[217,1286,394],{"class":239},[217,1288,227],{"class":226},[217,1290,279],{"class":233},[217,1292,174],{"class":222},[217,1294,403],{"class":239},[217,1296,227],{"class":226},[217,1298,408],{"class":233},[217,1300,174],{"class":222},[217,1302,413],{"class":239},[217,1304,227],{"class":226},[217,1306,63],{"class":245},[217,1308,1309],{"class":222},").reset_index()\n",[10,1311,1312],{},"Remember the calculation order: Python cells run across each row from column A, then down to the next row, sheet\nby sheet. Put load cells above and to the left of everything that uses them, and keep them on the first sheet if\nseveral sheets share the data.",[153,1314,1316],{"id":1315},"step-7-guard-the-size-and-shape-of-a-spill","Step 7 — Guard the size and shape of a spill",[10,1318,1319,1320,1323],{},"A spill that is five rows today can be five hundred next quarter, and a result that grows into the cells below it\nturns into ",[23,1321,1322],{},"#SPILL!"," the moment it reaches somebody's notes. When a formula publishes a view to the grid, decide its\nmaximum size in code and make the truncation visible, rather than letting the data decide how much of the sheet it\ntakes.",[208,1325,1327],{"className":210,"code":1326,"language":212,"meta":213,"style":213},"sales = xl(\"Sales[#All]\", headers=True)\nMAX_ROWS = 15\n\nranked = (\n    sales.groupby(\"Rep\", as_index=False)[\"Amount\"].sum()\n         .sort_values(\"Amount\", ascending=False)\n         .reset_index(drop=True)\n)\nshown = ranked.head(MAX_ROWS)\nif len(ranked) > MAX_ROWS:\n    rest = pd.DataFrame({\"Rep\": [f\"{len(ranked) - MAX_ROWS} others\"],\n                         \"Amount\": [ranked[\"Amount\"].iloc[MAX_ROWS:].sum()]})\n    shown = pd.concat([shown, rest], ignore_index=True)\nshown\n",[23,1328,1329,1349,1360,1364,1373,1394,1410,1424,1428,1442,1462,1505,1523,1542],{"__ignoreMap":213},[217,1330,1331,1333,1335,1337,1339,1341,1343,1345,1347],{"class":84,"line":219},[217,1332,223],{"class":222},[217,1334,227],{"class":226},[217,1336,230],{"class":222},[217,1338,234],{"class":233},[217,1340,174],{"class":222},[217,1342,240],{"class":239},[217,1344,227],{"class":226},[217,1346,246],{"class":245},[217,1348,249],{"class":222},[217,1350,1351,1354,1357],{"class":84,"line":252},[217,1352,1353],{"class":245},"MAX_ROWS",[217,1355,1356],{"class":226}," =",[217,1358,1359],{"class":245}," 15\n",[217,1361,1362],{"class":84,"line":285},[217,1363,538],{"emptyLinePlaceholder":537},[217,1365,1366,1369,1371],{"class":84,"line":551},[217,1367,1368],{"class":222},"ranked ",[217,1370,227],{"class":226},[217,1372,548],{"class":222},[217,1374,1375,1378,1380,1382,1384,1386,1388,1390,1392],{"class":84,"line":571},[217,1376,1377],{"class":222},"    sales.groupby(",[217,1379,380],{"class":233},[217,1381,174],{"class":222},[217,1383,268],{"class":239},[217,1385,227],{"class":226},[217,1387,273],{"class":245},[217,1389,276],{"class":222},[217,1391,279],{"class":233},[217,1393,282],{"class":222},[217,1395,1396,1398,1400,1402,1404,1406,1408],{"class":84,"line":606},[217,1397,636],{"class":222},[217,1399,279],{"class":233},[217,1401,174],{"class":222},[217,1403,643],{"class":239},[217,1405,227],{"class":226},[217,1407,273],{"class":245},[217,1409,249],{"class":222},[217,1411,1412,1415,1418,1420,1422],{"class":84,"line":633},[217,1413,1414],{"class":222},"         .reset_index(",[217,1416,1417],{"class":239},"drop",[217,1419,227],{"class":226},[217,1421,246],{"class":245},[217,1423,249],{"class":222},[217,1425,1426],{"class":84,"line":652},[217,1427,249],{"class":222},[217,1429,1430,1433,1435,1438,1440],{"class":84,"line":661},[217,1431,1432],{"class":222},"shown ",[217,1434,227],{"class":226},[217,1436,1437],{"class":222}," ranked.head(",[217,1439,1353],{"class":245},[217,1441,249],{"class":222},[217,1443,1444,1447,1450,1453,1456,1459],{"class":84,"line":683},[217,1445,1446],{"class":226},"if",[217,1448,1449],{"class":245}," len",[217,1451,1452],{"class":222},"(ranked) ",[217,1454,1455],{"class":226},">",[217,1457,1458],{"class":245}," MAX_ROWS",[217,1460,1461],{"class":222},":\n",[217,1463,1464,1467,1469,1472,1474,1477,1480,1483,1486,1489,1491,1494,1496,1499,1502],{"class":84,"line":694},[217,1465,1466],{"class":222},"    rest ",[217,1468,227],{"class":226},[217,1470,1471],{"class":222}," pd.DataFrame({",[217,1473,380],{"class":233},[217,1475,1476],{"class":222},": [",[217,1478,1479],{"class":226},"f",[217,1481,1482],{"class":233},"\"",[217,1484,671],{"class":1485},"sSjpA",[217,1487,1488],{"class":245},"len",[217,1490,1452],{"class":222},[217,1492,1493],{"class":226},"-",[217,1495,1458],{"class":245},[217,1497,1498],{"class":1485},"}",[217,1500,1501],{"class":233}," others\"",[217,1503,1504],{"class":222},"],\n",[217,1506,1507,1510,1513,1515,1518,1520],{"class":84,"line":699},[217,1508,1509],{"class":233},"                         \"Amount\"",[217,1511,1512],{"class":222},": [ranked[",[217,1514,279],{"class":233},[217,1516,1517],{"class":222},"].iloc[",[217,1519,1353],{"class":245},[217,1521,1522],{"class":222},":].sum()]})\n",[217,1524,1525,1528,1530,1533,1536,1538,1540],{"class":84,"line":1154},[217,1526,1527],{"class":222},"    shown ",[217,1529,227],{"class":226},[217,1531,1532],{"class":222}," pd.concat([shown, rest], ",[217,1534,1535],{"class":239},"ignore_index",[217,1537,227],{"class":226},[217,1539,246],{"class":245},[217,1541,249],{"class":222},[217,1543,1545],{"class":84,"line":1544},14,[217,1546,1547],{"class":222},"shown\n",[10,1549,1550],{},"The \"others\" row keeps the column total correct while capping the height at sixteen rows, so the block below can be\nplaced with confidence. The same idea applies to width: a pivot whose columns come from data — one per region, one\nper month — grows sideways, so select the columns you intend to show explicitly instead of returning whatever the\npivot produced.",[153,1552,1554],{"id":1553},"common-pitfalls","Common pitfalls",[1556,1557,1558,1574],"table",{},[1559,1560,1561],"thead",{},[1562,1563,1564,1568,1571],"tr",{},[1565,1566,1567],"th",{},"Symptom",[1565,1569,1570],{},"Cause",[1565,1572,1573],{},"Fix",[1575,1576,1577,1591,1605,1617,1631,1642],"tbody",{},[1562,1578,1579,1585,1588],{},[1580,1581,1582,1583],"td",{},"Cell shows ",[23,1584,29],{},[1580,1586,1587],{},"Last line is an assignment",[1580,1589,1590],{},"End with the variable name as an expression",[1562,1592,1593,1599,1602],{},[1580,1594,1595,1596,1598],{},"Cell shows a ",[23,1597,25],{}," card",[1580,1600,1601],{},"Output type is Python object",[1580,1603,1604],{},"Switch to Excel value with Ctrl+Alt+Shift+M",[1562,1606,1607,1611,1614],{},[1580,1608,1609],{},[23,1610,1322],{},[1580,1612,1613],{},"Cells in the spill area are not empty",[1580,1615,1616],{},"Clear the block, or move the formula",[1562,1618,1619,1622,1625],{},[1580,1620,1621],{},"Group names missing from the spill",[1580,1623,1624],{},"Keys are in the index",[1580,1626,1627,1628,1630],{},"Call ",[23,1629,707],{}," before returning",[1562,1632,1633,1636,1639],{},[1580,1634,1635],{},"Dates shown as numbers",[1580,1637,1638],{},"Spill has no number format",[1580,1640,1641],{},"Format the spill range in Excel",[1562,1643,1644,1650,1653],{},[1580,1645,1646,1647],{},"Later cell raises ",[23,1648,1649],{},"NameError",[1580,1651,1652],{},"It calculates before the cell defining the variable",[1580,1654,1655],{},"Move the definition up or left",[153,1657,1659],{"id":1658},"performance-and-scale-notes","Performance and scale notes",[10,1661,1662,1663,1666],{},"Converting a result to Excel values costs time proportional to the number of cells written, and a spill of tens of\nthousands of rows makes every recalculation slower and the workbook heavier. Return aggregated views to the grid and\nkeep row-level data as Python objects. If a sheet has many Python cells, ",[203,1664,1665],{},"Partial"," calculation mode stops them\nrecalculating on every edit; press F9 when you want fresh results.",[153,1668,1670],{"id":1669},"conclusion","Conclusion",[10,1672,1673,1674,1677,1678,1681],{},"A Python formula returns its last expression, and its output type decides where that result goes. Keep\nintermediate DataFrames as Python objects so they stay in one cell and can be reused; switch the final views to\nExcel values so charts, formulas and people can see them. Shape frames before they spill — ",[23,1675,1676],{},"reset_index",", rounding,\nrenaming, ",[23,1679,1680],{},"head"," — return plain scalars for single numbers, and format spill ranges in Excel rather than turning\nnumbers into text. Structure the sheet as one load cell feeding several small output cells, in calculation order.",[153,1683,1685],{"id":1684},"frequently-asked-questions","Frequently asked questions",[10,1687,1688,1691],{},[203,1689,1690],{},"How do I return more than one result from a single Python cell?","\nA cell returns one value. Return a DataFrame that combines the results, or assign each result to a variable and return them from separate cells, which is usually clearer.",[10,1693,1694,1697],{},[203,1695,1696],{},"Can an Excel formula use a value from a Python object cell?","\nSwitch that cell's output to Excel value first. Ordinary formulas and charts work with converted values, not with Python objects.",[10,1699,1700,1703],{},[203,1701,1702],{},"Why does my DataFrame spill with an extra column of numbers?","\nThat column is the index. Call reset_index(drop=True) to discard a meaningless index, or reset_index() to keep meaningful index labels as a named column.",[10,1705,1706,1709],{},[203,1707,1708],{},"Does formatting on the spill range survive recalculation?","\nYes. Number formats, fonts and fills applied to the cells stay in place when the formula recalculates, as long as the spill still covers those cells.",[153,1711,1713],{"id":1712},"related","Related",[158,1715,1716,1722,1727,1734,1741],{},[161,1717,1718,1719,1721],{},"Up one level: ",[32,1720,35],{"href":34}," — the full picture of =PY formulas and where they fit.",[161,1723,1724,1726],{},[32,1725,189],{"href":188}," — the input side of the same formulas.",[161,1728,1729,1733],{},[32,1730,1732],{"href":1731},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fplot-charts-with-matplotlib-in-python-in-excel\u002F","Plot Charts with matplotlib in Python in Excel"," — returning images instead of values.",[161,1735,1736,1740],{},[32,1737,1739],{"href":1738},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Ffix-python-in-excel-errors\u002F","Fix Python in Excel Errors"," — #SPILL!, #PYTHON! and the rest.",[161,1742,1743,1747],{},[32,1744,1746],{"href":1745},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fcreate-pivot-table-from-excel-with-pandas\u002F","Create a Pivot Table from Excel with Pandas"," — the pivot_table options used above.",[1749,1750,1751],"style",{},"html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}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 .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 .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}",{"title":213,"searchDepth":252,"depth":252,"links":1753},[1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766],{"id":155,"depth":252,"text":156},{"id":193,"depth":252,"text":194},{"id":308,"depth":252,"text":309},{"id":503,"depth":252,"text":504},{"id":715,"depth":252,"text":716},{"id":1038,"depth":252,"text":1039},{"id":1167,"depth":252,"text":1168},{"id":1315,"depth":252,"text":1316},{"id":1553,"depth":252,"text":1554},{"id":1658,"depth":252,"text":1659},{"id":1669,"depth":252,"text":1670},{"id":1684,"depth":252,"text":1685},{"id":1712,"depth":252,"text":1713},"2026-09-17","A =PY cell returns its last expression, either as a Python object card or spilled into the grid as Excel values. Shape DataFrames for the grid, avoid #SPILL!, and chain cells without recomputing.","md",[1771,1773,1775,1777],{"q":1690,"a":1772},"A cell returns one value. Return a DataFrame that combines the results, or assign each result to a variable and return them from separate cells, which is usually clearer.",{"q":1696,"a":1774},"Switch that cell's output to Excel value first. Ordinary formulas and charts work with converted values, not with Python objects.",{"q":1702,"a":1776},"That column is the index. Call reset_index(drop=True) to discard a meaningless index, or reset_index() to keep meaningful index labels as a named column.",{"q":1708,"a":1778},"Yes. Number formats, fonts and fills applied to the cells stay in place when the formula recalculates, as long as the spill still covers those cells.","return dataframes and values from python in excel cells",null,{"breadcrumb":1782},[1783,1786,1789],{"name":1784,"item":1785},"Home","\u002F",{"name":1787,"item":1788},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":35,"item":34},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freturn-dataframes-and-values-from-python-in-excel-cells",{"title":5,"description":1792},"Control what a Python in Excel formula returns: the last-expression rule, Python object versus Excel value output, shaping DataFrames for spilling, number formats, and reusing results across cells.","return-dataframes-and-values-from-python-in-excel-cells","getting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freturn-dataframes-and-values-from-python-in-excel-cells\u002Findex",[1796,1797],"python-in-excel","pandas","how-to","ecbC5VfsSlVJC-M5hSPOzDz-w4u4IUZXfUx1t1K9rqk",[1801,1804],{"title":189,"path":1802,"stem":1803,"children":-1},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel","getting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel\u002Findex",{"title":1805,"path":1806,"stem":1807,"children":-1},"Run a Regression with Python in Excel","\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Frun-a-regression-with-python-in-excel","getting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Frun-a-regression-with-python-in-excel\u002Findex",[1809,1811],{"path":1810,"title":1787},"\u002Fgetting-started-with-python-excel-automation",{"path":1812,"title":35},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel",[],[1815,1818,1821,1824,1827,1829],{"path":1816,"title":1817,"kind":1798},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fclean-data-with-pandas-in-python-in-excel","Clean Data with pandas in Python in Excel",{"path":1819,"title":1739,"kind":1820},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Ffix-python-in-excel-errors","fix",{"path":1822,"title":1823,"kind":1798},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fforecast-a-time-series-with-python-in-excel","Forecast a Time Series with Python in Excel",{"path":1825,"title":1826,"kind":1798},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fget-external-data-into-python-in-excel","Get External Data into Python in Excel with Power Query",{"path":1828,"title":1732,"kind":1798},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fplot-charts-with-matplotlib-in-python-in-excel",{"path":1830,"title":1831,"kind":1832},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fpython-in-excel-vs-openpyxl-and-xlwings","Python in Excel vs openpyxl and xlwings","compare",1790972075463]