[{"data":1,"prerenderedAt":2316},["ShallowReactive",2],{"doc:\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fvstack-hstack-take-and-choosecols-equivalents-in-pandas":3,"surround:\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fvstack-hstack-take-and-choosecols-equivalents-in-pandas":2283,"ancestors:\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fvstack-hstack-take-and-choosecols-equivalents-in-pandas":2291,"children:\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fvstack-hstack-take-and-choosecols-equivalents-in-pandas":2296,"related:\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fvstack-hstack-take-and-choosecols-equivalents-in-pandas":2297},{"id":4,"title":5,"body":6,"dateModified":2249,"datePublished":2249,"description":2250,"extension":2251,"faq":2252,"keyword":2261,"kind":2262,"meta":2263,"navigation":143,"path":2272,"seo":2273,"slug":2276,"stem":2277,"topics":2278,"type":2281,"__hash__":2282},"docs\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fvstack-hstack-take-and-choosecols-equivalents-in-pandas\u002Findex.md","VSTACK, HSTACK, TAKE and CHOOSECOLS Equivalents in pandas",{"type":7,"value":8,"toc":2235},"minimark",[9,49,54,85,111,115,235,261,493,499,568,572,582,667,688,692,758,804,808,811,973,980,1122,1126,1134,1355,1394,1398,1830,1874,1995,1999,2018,2022,2104,2108,2152,2156,2166,2179,2192,2198,2202,2231],[10,11,12,13,17,18,21,22,25,26,29,30,34,35,38,39,42,43,48],"p",{},"Excel 365's array functions made it possible to reshape data without helper columns: ",[14,15,16],"code",{},"VSTACK"," appends the monthly sheets into one list, ",[14,19,20],{},"CHOOSECOLS"," keeps the columns a report needs, ",[14,23,24],{},"TAKE"," shows the first or last few rows, and ",[14,27,28],{},"TOCOL"," flattens a grid into a single column. They read almost like pandas — and most of them map to a single pandas call. The exception is important: Excel stacks ranges by ",[31,32,33],"em",{},"position",", while pandas aligns by ",[31,36,37],{},"column name"," (for rows) and ",[31,40,41],{},"index"," (for columns), so the same-looking operation can line data up differently. This page maps each function and verifies the results against the spreadsheet itself. It belongs to ",[44,45,47],"a",{"href":46},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002F","Excel Formula Equivalents in pandas",".",[50,51,53],"h2",{"id":52},"prerequisites","Prerequisites",[55,56,61],"pre",{"className":57,"code":58,"language":59,"meta":60,"style":60},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas numpy openpyxl\n","bash","",[14,62,63],{"__ignoreMap":60},[64,65,68,72,76,79,82],"span",{"class":66,"line":67},"line",1,[64,69,71],{"class":70},"sMTad","pip",[64,73,75],{"class":74},"srMev"," install",[64,77,78],{"class":74}," pandas",[64,80,81],{"class":74}," numpy",[64,83,84],{"class":74}," openpyxl\n",[10,86,87,90,91,94,95,98,99,102,103,106,107,110],{},[14,88,89],{},"months.xlsx"," has a ",[14,92,93],{},"Jan"," and a ",[14,96,97],{},"Feb"," sheet with the same three fields — except that whoever built February put ",[14,100,101],{},"Orders"," before ",[14,104,105],{},"Sales",". That small inconsistency is exactly where position-based and name-based stacking part ways. LibreOffice (",[14,108,109],{},"soffice",") evaluates the Excel formulas in Step 6; recent versions support these functions.",[50,112,114],{"id":113},"step-1-vstack-append-rows","Step 1 — VSTACK: append rows",[55,116,120],{"className":117,"code":118,"language":119,"meta":60,"style":60},"language-python shiki shiki-themes github-light github-dark-high-contrast","import pandas as pd\n\nsheets = pd.read_excel(\"months.xlsx\", sheet_name=None)\nstacked = pd.concat(sheets, names=[\"Month\", None]).reset_index(level=0)\nprint(stacked.reset_index(drop=True))\n","python",[14,121,122,138,145,176,215],{"__ignoreMap":60},[64,123,124,128,132,135],{"class":66,"line":67},[64,125,127],{"class":126},"s-kum","import",[64,129,131],{"class":130},"skGVy"," pandas ",[64,133,134],{"class":126},"as",[64,136,137],{"class":130}," pd\n",[64,139,141],{"class":66,"line":140},2,[64,142,144],{"emptyLinePlaceholder":143},true,"\n",[64,146,148,151,154,157,160,163,167,169,173],{"class":66,"line":147},3,[64,149,150],{"class":130},"sheets ",[64,152,153],{"class":126},"=",[64,155,156],{"class":130}," pd.read_excel(",[64,158,159],{"class":74},"\"months.xlsx\"",[64,161,162],{"class":130},", ",[64,164,166],{"class":165},"sa561","sheet_name",[64,168,153],{"class":126},[64,170,172],{"class":171},"sP0c6","None",[64,174,175],{"class":130},")\n",[64,177,179,182,184,187,190,192,195,198,200,202,205,208,210,213],{"class":66,"line":178},4,[64,180,181],{"class":130},"stacked ",[64,183,153],{"class":126},[64,185,186],{"class":130}," pd.concat(sheets, ",[64,188,189],{"class":165},"names",[64,191,153],{"class":126},[64,193,194],{"class":130},"[",[64,196,197],{"class":74},"\"Month\"",[64,199,162],{"class":130},[64,201,172],{"class":171},[64,203,204],{"class":130},"]).reset_index(",[64,206,207],{"class":165},"level",[64,209,153],{"class":126},[64,211,212],{"class":171},"0",[64,214,175],{"class":130},[64,216,218,221,224,227,229,232],{"class":66,"line":217},5,[64,219,220],{"class":171},"print",[64,222,223],{"class":130},"(stacked.reset_index(",[64,225,226],{"class":165},"drop",[64,228,153],{"class":126},[64,230,231],{"class":171},"True",[64,233,234],{"class":130},"))\n",[10,236,237,240,241,244,245,247,248,250,251,253,254,257,258,260],{},[14,238,239],{},"pd.concat"," aligns the frames by column ",[31,242,243],{},"name",", so February's ",[14,246,105],{}," lands under ",[14,249,105],{}," even though it is the third column in that sheet. Passing the dictionary of sheets labels each row with its source sheet, which ",[14,252,16],{}," cannot do. ",[14,255,256],{},"=VSTACK(Jan!A2:C3, Feb!A2:C4)"," stacks by ",[31,259,33],{},": February's orders would appear in the Sales column and its sales in Orders — a silent swap that the spreadsheet will happily total. When the sheets genuinely share a layout the results are identical; when they do not, pandas is right and Excel is not.",[262,263,271,272,271,276,271,280,271,287,271,296,271,303,271,307,271,310,271,314,271,317,271,322,271,327,271,329,271,332,271,334,271,337,271,340,271,344,271,346,271,349,271,351,271,354,271,357,271,360,271,364,271,368,271,370,271,373,271,376,271,380,271,382,271,385,271,387,271,389,271,392,271,395,271,398,271,401,271,404,271,407,271,409,271,411,271,413,271,415,271,417,271,419,271,421,271,423,271,425,271,427,271,429,271,431,271,433,271,435,271,439,271,442,271,444,271,446,271,448,271,450,271,452,271,454,271,456,271,458,271,464,271,468,271,474,271,479,271,487],"svg",{"viewBox":264,"role":265,"ariaLabelledBy":266,"xmlns":269,"style":270},"128 0 504 196","img",[267,268],"vs-align-t","vs-align-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:504px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[273,274,275],"title",{"id":267},"Stacking by position versus by name",[277,278,279],"desc",{"id":268},"January has columns Region, Sales, Orders and February has Region, Orders, Sales. Stacked by position, as VSTACK does, February's orders fall under Sales. Stacked by name, as pd.concat does, each value stays in its own column.",[281,282],"rect",{"x":283,"y":212,"width":284,"height":285,"fill":286},"128","504","196","#ffffff",[281,288],{"x":289,"y":290,"width":291,"height":292,"rx":212,"fill":293,"stroke":294,"style":295},"144.3","40.0","61.4","28.0","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.5px",[297,298,302],"text",{"x":299,"y":300,"style":301},"175.0","59.0","font-size:10.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Region",[281,304],{"x":305,"y":290,"width":306,"height":292,"rx":212,"fill":293,"stroke":294,"style":295},"205.7","53.4",[297,308,105],{"x":309,"y":300,"style":301},"232.4",[281,311],{"x":312,"y":290,"width":313,"height":292,"rx":212,"fill":293,"stroke":294,"style":295},"259.1","61.2",[297,315,101],{"x":316,"y":300,"style":301},"289.7",[281,318],{"x":289,"y":319,"width":291,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},"68.0","var(--line,#cdd5e6)","stroke-width:1px",[297,323,326],{"x":299,"y":324,"style":325},"87.0","font-size:10.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","North",[281,328],{"x":305,"y":319,"width":306,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,330,331],{"x":309,"y":324,"style":325},"10",[281,333],{"x":312,"y":319,"width":313,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,335,336],{"x":316,"y":324,"style":325},"1",[281,338],{"x":289,"y":339,"width":291,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},"96.0",[297,341,343],{"x":299,"y":342,"style":325},"115.0","South",[281,345],{"x":305,"y":339,"width":306,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,347,348],{"x":309,"y":342,"style":325},"5",[281,350],{"x":312,"y":339,"width":313,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,352,353],{"x":316,"y":342,"style":325},"2",[281,355],{"x":289,"y":356,"width":291,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},"124.0",[297,358,326],{"x":299,"y":359,"style":325},"143.0",[281,361],{"x":305,"y":356,"width":306,"height":292,"rx":212,"fill":362,"stroke":363,"style":295},"#fce9e9","var(--danger,#dc2626)",[297,365,367],{"x":309,"y":359,"style":366},"font-size:10.5px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","3",[281,369],{"x":312,"y":356,"width":313,"height":292,"rx":212,"fill":362,"stroke":363,"style":295},[297,371,372],{"x":316,"y":359,"style":366},"7",[281,374],{"x":289,"y":375,"width":291,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},"152.0",[297,377,379],{"x":299,"y":378,"style":325},"171.0","East",[281,381],{"x":305,"y":375,"width":306,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,383,384],{"x":309,"y":378,"style":325},"4",[281,386],{"x":312,"y":375,"width":313,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,388,384],{"x":316,"y":378,"style":325},[281,390],{"x":391,"y":290,"width":291,"height":292,"rx":212,"fill":293,"stroke":294,"style":295},"439.8",[297,393,302],{"x":394,"y":300,"style":301},"470.5",[281,396],{"x":397,"y":290,"width":306,"height":292,"rx":212,"fill":293,"stroke":294,"style":295},"501.2",[297,399,105],{"x":400,"y":300,"style":301},"527.8",[281,402],{"x":403,"y":290,"width":313,"height":292,"rx":212,"fill":293,"stroke":294,"style":295},"554.5",[297,405,101],{"x":406,"y":300,"style":301},"585.1",[281,408],{"x":391,"y":319,"width":291,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,410,326],{"x":394,"y":324,"style":325},[281,412],{"x":397,"y":319,"width":306,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,414,331],{"x":400,"y":324,"style":325},[281,416],{"x":403,"y":319,"width":313,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,418,336],{"x":406,"y":324,"style":325},[281,420],{"x":391,"y":339,"width":291,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,422,343],{"x":394,"y":342,"style":325},[281,424],{"x":397,"y":339,"width":306,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,426,348],{"x":400,"y":342,"style":325},[281,428],{"x":403,"y":339,"width":313,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,430,353],{"x":406,"y":342,"style":325},[281,432],{"x":391,"y":356,"width":291,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,434,326],{"x":394,"y":359,"style":325},[281,436],{"x":397,"y":356,"width":306,"height":292,"rx":212,"fill":437,"stroke":438,"style":295},"#d9f4f1","var(--teal,#0f9488)",[297,440,372],{"x":400,"y":359,"style":441},"font-size:10.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle",[281,443],{"x":403,"y":356,"width":313,"height":292,"rx":212,"fill":437,"stroke":438,"style":295},[297,445,367],{"x":406,"y":359,"style":441},[281,447],{"x":391,"y":375,"width":291,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,449,379],{"x":394,"y":378,"style":325},[281,451],{"x":397,"y":375,"width":306,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,453,384],{"x":400,"y":378,"style":325},[281,455],{"x":403,"y":375,"width":313,"height":292,"rx":212,"fill":286,"stroke":320,"style":321},[297,457,384],{"x":406,"y":378,"style":325},[297,459,463],{"x":460,"y":461,"style":462},"232.3","29.0","font-size:12.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","VSTACK (by position)",[297,465,467],{"x":466,"y":461,"style":462},"527.7","pd.concat (by name)",[66,469],{"x1":470,"y1":471,"x2":472,"y2":471,"stroke":294,"style":473},"330.2","110.0","425.8","stroke-width:2px",[475,476],"polygon",{"points":477,"fill":478},"429.8,110.0 420.8,115.0 420.8,105.0","#5b5cf0",[281,480],{"x":481,"y":482,"width":483,"height":484,"rx":485,"fill":286,"stroke":320,"style":486},"348.2","77.0","63.6","22.0","11","stroke-width:1.2px",[297,488,492],{"x":489,"y":490,"style":491},"380.0","92.0","font-size:11.5px;font-weight:400;fill:var(--brand-strong,#4338ca);text-anchor:middle;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace","concat",[10,494,495,496,498],{},"To reproduce ",[14,497,16],{}," exactly — for example to match a workbook that already contains it — ignore the headers and stack the raw values:",[55,500,502],{"className":117,"code":501,"language":119,"meta":60,"style":60},"by_position = pd.DataFrame(\n    [row for df in sheets.values() for row in df.to_numpy().tolist()],\n    columns=sheets[\"Jan\"].columns,\n)\nprint(by_position)\n",[14,503,504,514,541,557,561],{"__ignoreMap":60},[64,505,506,509,511],{"class":66,"line":67},[64,507,508],{"class":130},"by_position ",[64,510,153],{"class":126},[64,512,513],{"class":130}," pd.DataFrame(\n",[64,515,516,519,522,525,528,531,533,536,538],{"class":66,"line":140},[64,517,518],{"class":130},"    [row ",[64,520,521],{"class":126},"for",[64,523,524],{"class":130}," df ",[64,526,527],{"class":126},"in",[64,529,530],{"class":130}," sheets.values() ",[64,532,521],{"class":126},[64,534,535],{"class":130}," row ",[64,537,527],{"class":126},[64,539,540],{"class":130}," df.to_numpy().tolist()],\n",[64,542,543,546,548,551,554],{"class":66,"line":147},[64,544,545],{"class":165},"    columns",[64,547,153],{"class":126},[64,549,550],{"class":130},"sheets[",[64,552,553],{"class":74},"\"Jan\"",[64,555,556],{"class":130},"].columns,\n",[64,558,559],{"class":66,"line":178},[64,560,175],{"class":130},[64,562,563,565],{"class":66,"line":217},[64,564,220],{"class":171},[64,566,567],{"class":130},"(by_position)\n",[50,569,571],{"id":570},"step-2-hstack-put-ranges-side-by-side","Step 2 — HSTACK: put ranges side by side",[10,573,574,577,578,581],{},[14,575,576],{},"HSTACK"," places ranges next to each other by position; ",[14,579,580],{},"pd.concat(axis=1)"," aligns on the index:",[55,583,585],{"className":117,"code":584,"language":119,"meta":60,"style":60},"left = sheets[\"Jan\"][[\"Region\", \"Sales\"]]\nright = sheets[\"Feb\"][[\"Region\", \"Sales\"]]\nprint(pd.concat([left, right], axis=1, keys=[\"Jan\", \"Feb\"]))\n",[14,586,587,613,635],{"__ignoreMap":60},[64,588,589,592,594,597,599,602,605,607,610],{"class":66,"line":67},[64,590,591],{"class":130},"left ",[64,593,153],{"class":126},[64,595,596],{"class":130}," sheets[",[64,598,553],{"class":74},[64,600,601],{"class":130},"][[",[64,603,604],{"class":74},"\"Region\"",[64,606,162],{"class":130},[64,608,609],{"class":74},"\"Sales\"",[64,611,612],{"class":130},"]]\n",[64,614,615,618,620,622,625,627,629,631,633],{"class":66,"line":140},[64,616,617],{"class":130},"right ",[64,619,153],{"class":126},[64,621,596],{"class":130},[64,623,624],{"class":74},"\"Feb\"",[64,626,601],{"class":130},[64,628,604],{"class":74},[64,630,162],{"class":130},[64,632,609],{"class":74},[64,634,612],{"class":130},[64,636,637,639,642,645,647,649,651,654,656,658,660,662,664],{"class":66,"line":147},[64,638,220],{"class":171},[64,640,641],{"class":130},"(pd.concat([left, right], ",[64,643,644],{"class":165},"axis",[64,646,153],{"class":126},[64,648,336],{"class":171},[64,650,162],{"class":130},[64,652,653],{"class":165},"keys",[64,655,153],{"class":126},[64,657,194],{"class":130},[64,659,553],{"class":74},[64,661,162],{"class":130},[64,663,624],{"class":74},[64,665,666],{"class":130},"]))\n",[10,668,669,670,672,673,676,677,680,681,683,684,48],{},"Both frames have a default index 0, 1, 2, so row 0 meets row 0 — position and index coincide, and the result matches ",[14,671,576],{},". The third February row has no January partner and gets ",[14,674,675],{},"NaN",", where Excel pads the shorter range with ",[14,678,679],{},"#N\u002FA",". Note that North and North happen to align, but South sits next to East: neither tool matches ",[31,682,653],{},". Side-by-side comparisons by region need a merge on the key instead, as in ",[44,685,687],{"href":686},"\u002Fadvanced-data-transformation-and-cleaning\u002Fmerging-and-joining-excel-dataframes\u002Fmerge-two-excel-files-on-common-column-python\u002F","Merge Two Excel Files on a Common Column with Python",[50,689,691],{"id":690},"step-3-take-and-drop","Step 3 — TAKE and DROP",[55,693,695],{"className":117,"code":694,"language":119,"meta":60,"style":60},"data = stacked.reset_index(drop=True)\nprint(data.head(2), data.tail(2), data.iloc[2:], data.iloc[:, :2], sep=\"\\n\\n\")\n",[14,696,697,715],{"__ignoreMap":60},[64,698,699,702,704,707,709,711,713],{"class":66,"line":67},[64,700,701],{"class":130},"data ",[64,703,153],{"class":126},[64,705,706],{"class":130}," stacked.reset_index(",[64,708,226],{"class":165},[64,710,153],{"class":126},[64,712,231],{"class":171},[64,714,175],{"class":130},[64,716,717,719,722,724,727,729,732,734,737,739,742,745,747,750,754,756],{"class":66,"line":140},[64,718,220],{"class":171},[64,720,721],{"class":130},"(data.head(",[64,723,353],{"class":171},[64,725,726],{"class":130},"), data.tail(",[64,728,353],{"class":171},[64,730,731],{"class":130},"), data.iloc[",[64,733,353],{"class":171},[64,735,736],{"class":130},":], data.iloc[:, :",[64,738,353],{"class":171},[64,740,741],{"class":130},"], ",[64,743,744],{"class":165},"sep",[64,746,153],{"class":126},[64,748,749],{"class":74},"\"",[64,751,753],{"class":752},"sSjpA","\\n\\n",[64,755,749],{"class":74},[64,757,175],{"class":130},[10,759,760,763,764,767,768,763,771,774,775,763,778,767,781,763,784,787,788,791,792,795,796,798,799,803],{},[14,761,762],{},"TAKE(range, 2)"," is ",[14,765,766],{},"head(2)"," and ",[14,769,770],{},"TAKE(range, -2)",[14,772,773],{},"tail(2)","; ",[14,776,777],{},"DROP(range, 2)",[14,779,780],{},"iloc[2:]",[14,782,783],{},"DROP(range, -2)",[14,785,786],{},"iloc[:-2]",". Both Excel functions also take a column count — ",[14,789,790],{},"TAKE(range, , 2)"," keeps the first two columns, ",[14,793,794],{},"iloc[:, :2]",". Combined with a sort, ",[14,797,24],{}," is the usual way to show a top-N list; see ",[44,800,802],{"href":801},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fget-the-top-n-rows-per-group-in-pandas\u002F","Get the Top N Rows per Group in pandas"," for the grouped version.",[50,805,807],{"id":806},"step-4-choosecols-and-chooserows","Step 4 — CHOOSECOLS and CHOOSEROWS",[10,809,810],{},"Excel counts columns from 1 and counts negative numbers from the end; Python counts from 0. A tiny helper keeps the Excel numbering for anyone translating formulas line by line:",[55,812,814],{"className":117,"code":813,"language":119,"meta":60,"style":60},"def choosecols(df, *cols):\n    return df.iloc[:, [c - 1 if c > 0 else c for c in cols]]\n\ndef chooserows(df, *rows):\n    return df.iloc[[r - 1 if r > 0 else r for r in rows]]\n\nprint(choosecols(data, 1, 3))      # CHOOSECOLS(range, 1, 3)\nprint(chooserows(data, 1, -1))     # CHOOSEROWS(range, 1, -1): first and last rows\n",[14,815,816,834,874,878,892,925,930,951],{"__ignoreMap":60},[64,817,818,821,825,828,831],{"class":66,"line":67},[64,819,820],{"class":126},"def",[64,822,824],{"class":823},"s_Opv"," choosecols",[64,826,827],{"class":130},"(df, ",[64,829,830],{"class":126},"*",[64,832,833],{"class":130},"cols):\n",[64,835,836,839,842,845,848,851,854,857,860,863,865,867,869,871],{"class":66,"line":140},[64,837,838],{"class":126},"    return",[64,840,841],{"class":130}," df.iloc[:, [c ",[64,843,844],{"class":126},"-",[64,846,847],{"class":171}," 1",[64,849,850],{"class":126}," if",[64,852,853],{"class":130}," c ",[64,855,856],{"class":126},">",[64,858,859],{"class":171}," 0",[64,861,862],{"class":126}," else",[64,864,853],{"class":130},[64,866,521],{"class":126},[64,868,853],{"class":130},[64,870,527],{"class":126},[64,872,873],{"class":130}," cols]]\n",[64,875,876],{"class":66,"line":147},[64,877,144],{"emptyLinePlaceholder":143},[64,879,880,882,885,887,889],{"class":66,"line":178},[64,881,820],{"class":126},[64,883,884],{"class":823}," chooserows",[64,886,827],{"class":130},[64,888,830],{"class":126},[64,890,891],{"class":130},"rows):\n",[64,893,894,896,899,901,903,905,908,910,912,914,916,918,920,922],{"class":66,"line":217},[64,895,838],{"class":126},[64,897,898],{"class":130}," df.iloc[[r ",[64,900,844],{"class":126},[64,902,847],{"class":171},[64,904,850],{"class":126},[64,906,907],{"class":130}," r ",[64,909,856],{"class":126},[64,911,859],{"class":171},[64,913,862],{"class":126},[64,915,907],{"class":130},[64,917,521],{"class":126},[64,919,907],{"class":130},[64,921,527],{"class":126},[64,923,924],{"class":130}," rows]]\n",[64,926,928],{"class":66,"line":927},6,[64,929,144],{"emptyLinePlaceholder":143},[64,931,933,935,938,940,942,944,947],{"class":66,"line":932},7,[64,934,220],{"class":171},[64,936,937],{"class":130},"(choosecols(data, ",[64,939,336],{"class":171},[64,941,162],{"class":130},[64,943,367],{"class":171},[64,945,946],{"class":130},"))      ",[64,948,950],{"class":949},"s-wDw","# CHOOSECOLS(range, 1, 3)\n",[64,952,954,956,959,961,963,965,967,970],{"class":66,"line":953},8,[64,955,220],{"class":171},[64,957,958],{"class":130},"(chooserows(data, ",[64,960,336],{"class":171},[64,962,162],{"class":130},[64,964,844],{"class":126},[64,966,336],{"class":171},[64,968,969],{"class":130},"))     ",[64,971,972],{"class":949},"# CHOOSEROWS(range, 1, -1): first and last rows\n",[10,974,975,976,979],{},"In pandas code you would normally select by name — ",[14,977,978],{},"data[[\"Region\", \"Orders\"]]"," — which survives column reordering; the numeric helper is for faithful translation and for files whose headers cannot be trusted.",[262,981,271,987,271,990,271,993,271,997,271,1002,271,1006,271,1012,271,1015,271,1019,271,1024,271,1029,271,1031,271,1035,271,1037,271,1039,271,1042,271,1045,271,1047,271,1051,271,1053,271,1055,271,1057,271,1061,271,1063,271,1067,271,1069,271,1071,271,1074,271,1078,271,1080,271,1084,271,1086,271,1088,271,1091,271,1094,271,1096,271,1100,271,1102,271,1105,271,1108,271,1112,271,1114,271,1118,271,1120],{"viewBox":982,"role":265,"ariaLabelledBy":983,"xmlns":269,"style":986},"4 0 752 276",[984,985],"vs-map-t","vs-map-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[273,988,989],{"id":984},"Excel array-shaping functions and their pandas equivalents",[277,991,992],{"id":985},"VSTACK maps to pd.concat on rows, HSTACK to pd.concat with axis=1, TAKE to head or tail, DROP to iloc slicing, CHOOSECOLS and CHOOSEROWS to iloc with one-based positions converted, TOCOL to stack or numpy ravel, and WRAPROWS to numpy reshape.",[281,994],{"x":384,"y":212,"width":995,"height":996,"fill":286},"752","276",[281,998],{"x":999,"y":1000,"width":1001,"height":290,"rx":212,"fill":286,"stroke":320,"style":321},"20.0","16.0","228.8",[281,1003],{"x":1004,"y":1000,"width":1005,"height":290,"rx":212,"fill":293,"stroke":294,"style":486},"248.8","245.6",[297,1007,1011],{"x":1008,"y":1009,"style":1010},"371.6","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","pandas \u002F NumPy",[281,1013],{"x":1014,"y":1000,"width":1005,"height":290,"rx":212,"fill":293,"stroke":294,"style":486},"494.4",[297,1016,1018],{"x":1017,"y":1009,"style":1010},"617.2","aligns by",[281,1020],{"x":999,"y":1021,"width":1001,"height":1022,"rx":212,"fill":1023,"stroke":320,"style":321},"56.0","34.0","#e7ebef",[297,1025,16],{"x":1026,"y":1027,"style":1028},"32.0","78.0","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start",[281,1030],{"x":1004,"y":1021,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1032,1034],{"x":1008,"y":482,"style":1033},"font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","pd.concat([a, b])",[281,1036],{"x":1014,"y":1021,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1038,37],{"x":1017,"y":482,"style":1033},[281,1040],{"x":999,"y":1041,"width":1001,"height":1022,"rx":212,"fill":1023,"stroke":320,"style":321},"90.0",[297,1043,576],{"x":1026,"y":1044,"style":1028},"112.0",[281,1046],{"x":1004,"y":1041,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1048,1050],{"x":1008,"y":1049,"style":1033},"111.0","pd.concat([a, b], axis=1)",[281,1052],{"x":1014,"y":1041,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1054,41],{"x":1017,"y":1049,"style":1033},[281,1056],{"x":999,"y":356,"width":1001,"height":1022,"rx":212,"fill":1023,"stroke":320,"style":321},[297,1058,1060],{"x":1026,"y":1059,"style":1028},"146.0","TAKE \u002F DROP",[281,1062],{"x":1004,"y":356,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1064,1066],{"x":1008,"y":1065,"style":1033},"145.0","head, tail, iloc[n:]",[281,1068],{"x":1014,"y":356,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1070,33],{"x":1017,"y":1065,"style":1033},[281,1072],{"x":999,"y":1073,"width":1001,"height":1022,"rx":212,"fill":1023,"stroke":320,"style":321},"158.0",[297,1075,1077],{"x":1026,"y":1076,"style":1028},"180.0","CHOOSECOLS \u002F CHOOSEROWS",[281,1079],{"x":1004,"y":1073,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1081,1083],{"x":1008,"y":1082,"style":1033},"179.0","iloc with positions − 1",[281,1085],{"x":1014,"y":1073,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1087,33],{"x":1017,"y":1082,"style":1033},[281,1089],{"x":999,"y":1090,"width":1001,"height":1022,"rx":212,"fill":1023,"stroke":320,"style":321},"192.0",[297,1092,28],{"x":1026,"y":1093,"style":1028},"214.0",[281,1095],{"x":1004,"y":1090,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1097,1099],{"x":1008,"y":1098,"style":1033},"213.0","to_numpy().ravel()",[281,1101],{"x":1014,"y":1090,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1103,1104],{"x":1017,"y":1098,"style":1033},"row by row",[281,1106],{"x":999,"y":1107,"width":1001,"height":1022,"rx":212,"fill":1023,"stroke":320,"style":321},"226.0",[297,1109,1111],{"x":1026,"y":1110,"style":1028},"248.0","WRAPROWS",[281,1113],{"x":1004,"y":1107,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1115,1117],{"x":1008,"y":1116,"style":1033},"247.0","np.reshape \u002F np.pad",[281,1119],{"x":1014,"y":1107,"width":1005,"height":1022,"rx":212,"fill":286,"stroke":320,"style":321},[297,1121,33],{"x":1017,"y":1116,"style":1033},[50,1123,1125],{"id":1124},"step-5-tocol-and-wraprows","Step 5 — TOCOL and WRAPROWS",[10,1127,1128,1130,1131,1133],{},[14,1129,28],{}," flattens a grid into one column, reading row by row unless told otherwise; ",[14,1132,1111],{}," does the reverse, cutting a list into rows of a given width:",[55,1135,1137],{"className":117,"code":1136,"language":119,"meta":60,"style":60},"import numpy as np\n\ngrid = data[[\"Region\", \"Sales\", \"Orders\"]]\nprint(grid.to_numpy().ravel().tolist())                 # TOCOL(range)\nprint(grid.to_numpy().ravel(order=\"F\").tolist()[:5])     # TOCOL(range, , TRUE): by column\n\ndef wraprows(values, width, pad=None):\n    values = list(values)\n    values += [pad] * (-len(values) % width)\n    return pd.DataFrame(np.array(values, dtype=object).reshape(-1, width))\n\nprint(wraprows([\"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\"], 3))\n",[14,1138,1139,1151,1155,1178,1188,1214,1218,1235,1248,1278,1304,1309],{"__ignoreMap":60},[64,1140,1141,1143,1146,1148],{"class":66,"line":67},[64,1142,127],{"class":126},[64,1144,1145],{"class":130}," numpy ",[64,1147,134],{"class":126},[64,1149,1150],{"class":130}," np\n",[64,1152,1153],{"class":66,"line":140},[64,1154,144],{"emptyLinePlaceholder":143},[64,1156,1157,1160,1162,1165,1167,1169,1171,1173,1176],{"class":66,"line":147},[64,1158,1159],{"class":130},"grid ",[64,1161,153],{"class":126},[64,1163,1164],{"class":130}," data[[",[64,1166,604],{"class":74},[64,1168,162],{"class":130},[64,1170,609],{"class":74},[64,1172,162],{"class":130},[64,1174,1175],{"class":74},"\"Orders\"",[64,1177,612],{"class":130},[64,1179,1180,1182,1185],{"class":66,"line":178},[64,1181,220],{"class":171},[64,1183,1184],{"class":130},"(grid.to_numpy().ravel().tolist())                 ",[64,1186,1187],{"class":949},"# TOCOL(range)\n",[64,1189,1190,1192,1195,1198,1200,1203,1206,1208,1211],{"class":66,"line":217},[64,1191,220],{"class":171},[64,1193,1194],{"class":130},"(grid.to_numpy().ravel(",[64,1196,1197],{"class":165},"order",[64,1199,153],{"class":126},[64,1201,1202],{"class":74},"\"F\"",[64,1204,1205],{"class":130},").tolist()[:",[64,1207,348],{"class":171},[64,1209,1210],{"class":130},"])     ",[64,1212,1213],{"class":949},"# TOCOL(range, , TRUE): by column\n",[64,1215,1216],{"class":66,"line":927},[64,1217,144],{"emptyLinePlaceholder":143},[64,1219,1220,1222,1225,1228,1230,1232],{"class":66,"line":932},[64,1221,820],{"class":126},[64,1223,1224],{"class":823}," wraprows",[64,1226,1227],{"class":130},"(values, width, pad",[64,1229,153],{"class":126},[64,1231,172],{"class":171},[64,1233,1234],{"class":130},"):\n",[64,1236,1237,1240,1242,1245],{"class":66,"line":953},[64,1238,1239],{"class":130},"    values ",[64,1241,153],{"class":126},[64,1243,1244],{"class":171}," list",[64,1246,1247],{"class":130},"(values)\n",[64,1249,1251,1253,1256,1259,1261,1264,1266,1269,1272,1275],{"class":66,"line":1250},9,[64,1252,1239],{"class":130},[64,1254,1255],{"class":126},"+=",[64,1257,1258],{"class":130}," [pad] ",[64,1260,830],{"class":126},[64,1262,1263],{"class":130}," (",[64,1265,844],{"class":126},[64,1267,1268],{"class":171},"len",[64,1270,1271],{"class":130},"(values) ",[64,1273,1274],{"class":126},"%",[64,1276,1277],{"class":130}," width)\n",[64,1279,1281,1283,1286,1289,1291,1294,1297,1299,1301],{"class":66,"line":1280},10,[64,1282,838],{"class":126},[64,1284,1285],{"class":130}," pd.DataFrame(np.array(values, ",[64,1287,1288],{"class":165},"dtype",[64,1290,153],{"class":126},[64,1292,1293],{"class":171},"object",[64,1295,1296],{"class":130},").reshape(",[64,1298,844],{"class":126},[64,1300,336],{"class":171},[64,1302,1303],{"class":130},", width))\n",[64,1305,1307],{"class":66,"line":1306},11,[64,1308,144],{"emptyLinePlaceholder":143},[64,1310,1312,1314,1317,1320,1322,1325,1327,1330,1332,1335,1337,1340,1342,1344,1346,1349,1351,1353],{"class":66,"line":1311},12,[64,1313,220],{"class":171},[64,1315,1316],{"class":130},"(wraprows([",[64,1318,1319],{"class":74},"\"A\"",[64,1321,162],{"class":130},[64,1323,1324],{"class":74},"\"B\"",[64,1326,162],{"class":130},[64,1328,1329],{"class":74},"\"C\"",[64,1331,162],{"class":130},[64,1333,1334],{"class":74},"\"D\"",[64,1336,162],{"class":130},[64,1338,1339],{"class":74},"\"E\"",[64,1341,162],{"class":130},[64,1343,1202],{"class":74},[64,1345,162],{"class":130},[64,1347,1348],{"class":74},"\"G\"",[64,1350,741],{"class":130},[64,1352,367],{"class":171},[64,1354,234],{"class":130},[10,1356,1357,1360,1361,1363,1364,1367,1368,1371,1372,1375,1376,1378,1379,1382,1383,1385,1386,1389,1390,48],{},[14,1358,1359],{},"ravel()"," reads row by row like ",[14,1362,28],{},"'s default; ",[14,1365,1366],{},"order=\"F\""," reads column by column like its ",[14,1369,1370],{},"scan_by_column"," option. ",[14,1373,1374],{},"wraprows"," pads the last row, as ",[14,1377,1111],{}," does with its ",[14,1380,1381],{},"pad_with"," argument (without it Excel fills the gap with ",[14,1384,679],{},"). These are handy for turning a label list into a printable grid or flattening a matrix-style sheet before analysis — though for data, ",[14,1387,1388],{},"melt"," is usually the better tool, see ",[44,1391,1393],{"href":1392},"\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",[50,1395,1397],{"id":1396},"step-6-check-against-the-spreadsheet","Step 6 — Check against the spreadsheet",[55,1399,1401],{"className":117,"code":1400,"language":119,"meta":60,"style":60},"import subprocess\nfrom openpyxl import load_workbook\nfrom openpyxl.worksheet.formula import ArrayFormula\n\nwb = load_workbook(\"months.xlsx\")\nout = wb.create_sheet(\"Out\")\nout[\"A1\"] = ArrayFormula(\"A1:C5\", \"=_xlfn.VSTACK(Jan!A2:C3,Feb!A2:C4)\")\nout[\"E1\"] = ArrayFormula(\"E1:F5\", \"=_xlfn.CHOOSECOLS(A1:C5,1,3)\")\nout[\"H1\"] = ArrayFormula(\"H1:J2\", \"=_xlfn.TAKE(A1:C5,-2)\")\nout[\"A8\"] = ArrayFormula(\"A8:A22\", \"=_xlfn.TOCOL(A1:C5)\")\nwb.save(\"months_formulas.xlsx\")\nsubprocess.run([\"soffice\", \"--headless\", \"--convert-to\", \"xlsx\", \"--outdir\", \"recalc\", \"months_formulas.xlsx\"],\n               check=True, capture_output=True)\nws = load_workbook(\"recalc\u002Fmonths_formulas.xlsx\", data_only=True)[\"Out\"]\nvstack = [[c.value for c in row] for row in ws[\"A1:C5\"]]\nprint(\"VSTACK rows:\", vstack[2:4])\nprint(\"matches position-based stack:\", vstack == by_position.to_numpy().tolist())\nprint(\"TAKE -2:\", [[c.value for c in row] for row in ws[\"H1:J2\"]])\nprint(\"TOCOL first 6:\", [ws[f\"A{i}\"].value for i in range(8, 14)])\n",[14,1402,1403,1410,1423,1435,1439,1453,1468,1494,1517,1540,1563,1573,1613,1634,1664,1697,1721,1740,1774],{"__ignoreMap":60},[64,1404,1405,1407],{"class":66,"line":67},[64,1406,127],{"class":126},[64,1408,1409],{"class":130}," subprocess\n",[64,1411,1412,1415,1418,1420],{"class":66,"line":140},[64,1413,1414],{"class":126},"from",[64,1416,1417],{"class":130}," openpyxl ",[64,1419,127],{"class":126},[64,1421,1422],{"class":130}," load_workbook\n",[64,1424,1425,1427,1430,1432],{"class":66,"line":147},[64,1426,1414],{"class":126},[64,1428,1429],{"class":130}," openpyxl.worksheet.formula ",[64,1431,127],{"class":126},[64,1433,1434],{"class":130}," ArrayFormula\n",[64,1436,1437],{"class":66,"line":178},[64,1438,144],{"emptyLinePlaceholder":143},[64,1440,1441,1444,1446,1449,1451],{"class":66,"line":217},[64,1442,1443],{"class":130},"wb ",[64,1445,153],{"class":126},[64,1447,1448],{"class":130}," load_workbook(",[64,1450,159],{"class":74},[64,1452,175],{"class":130},[64,1454,1455,1458,1460,1463,1466],{"class":66,"line":927},[64,1456,1457],{"class":130},"out ",[64,1459,153],{"class":126},[64,1461,1462],{"class":130}," wb.create_sheet(",[64,1464,1465],{"class":74},"\"Out\"",[64,1467,175],{"class":130},[64,1469,1470,1473,1476,1479,1481,1484,1487,1489,1492],{"class":66,"line":932},[64,1471,1472],{"class":130},"out[",[64,1474,1475],{"class":74},"\"A1\"",[64,1477,1478],{"class":130},"] ",[64,1480,153],{"class":126},[64,1482,1483],{"class":130}," ArrayFormula(",[64,1485,1486],{"class":74},"\"A1:C5\"",[64,1488,162],{"class":130},[64,1490,1491],{"class":74},"\"=_xlfn.VSTACK(Jan!A2:C3,Feb!A2:C4)\"",[64,1493,175],{"class":130},[64,1495,1496,1498,1501,1503,1505,1507,1510,1512,1515],{"class":66,"line":953},[64,1497,1472],{"class":130},[64,1499,1500],{"class":74},"\"E1\"",[64,1502,1478],{"class":130},[64,1504,153],{"class":126},[64,1506,1483],{"class":130},[64,1508,1509],{"class":74},"\"E1:F5\"",[64,1511,162],{"class":130},[64,1513,1514],{"class":74},"\"=_xlfn.CHOOSECOLS(A1:C5,1,3)\"",[64,1516,175],{"class":130},[64,1518,1519,1521,1524,1526,1528,1530,1533,1535,1538],{"class":66,"line":1250},[64,1520,1472],{"class":130},[64,1522,1523],{"class":74},"\"H1\"",[64,1525,1478],{"class":130},[64,1527,153],{"class":126},[64,1529,1483],{"class":130},[64,1531,1532],{"class":74},"\"H1:J2\"",[64,1534,162],{"class":130},[64,1536,1537],{"class":74},"\"=_xlfn.TAKE(A1:C5,-2)\"",[64,1539,175],{"class":130},[64,1541,1542,1544,1547,1549,1551,1553,1556,1558,1561],{"class":66,"line":1280},[64,1543,1472],{"class":130},[64,1545,1546],{"class":74},"\"A8\"",[64,1548,1478],{"class":130},[64,1550,153],{"class":126},[64,1552,1483],{"class":130},[64,1554,1555],{"class":74},"\"A8:A22\"",[64,1557,162],{"class":130},[64,1559,1560],{"class":74},"\"=_xlfn.TOCOL(A1:C5)\"",[64,1562,175],{"class":130},[64,1564,1565,1568,1571],{"class":66,"line":1306},[64,1566,1567],{"class":130},"wb.save(",[64,1569,1570],{"class":74},"\"months_formulas.xlsx\"",[64,1572,175],{"class":130},[64,1574,1575,1578,1581,1583,1586,1588,1591,1593,1596,1598,1601,1603,1606,1608,1610],{"class":66,"line":1311},[64,1576,1577],{"class":130},"subprocess.run([",[64,1579,1580],{"class":74},"\"soffice\"",[64,1582,162],{"class":130},[64,1584,1585],{"class":74},"\"--headless\"",[64,1587,162],{"class":130},[64,1589,1590],{"class":74},"\"--convert-to\"",[64,1592,162],{"class":130},[64,1594,1595],{"class":74},"\"xlsx\"",[64,1597,162],{"class":130},[64,1599,1600],{"class":74},"\"--outdir\"",[64,1602,162],{"class":130},[64,1604,1605],{"class":74},"\"recalc\"",[64,1607,162],{"class":130},[64,1609,1570],{"class":74},[64,1611,1612],{"class":130},"],\n",[64,1614,1616,1619,1621,1623,1625,1628,1630,1632],{"class":66,"line":1615},13,[64,1617,1618],{"class":165},"               check",[64,1620,153],{"class":126},[64,1622,231],{"class":171},[64,1624,162],{"class":130},[64,1626,1627],{"class":165},"capture_output",[64,1629,153],{"class":126},[64,1631,231],{"class":171},[64,1633,175],{"class":130},[64,1635,1637,1640,1642,1644,1647,1649,1652,1654,1656,1659,1661],{"class":66,"line":1636},14,[64,1638,1639],{"class":130},"ws ",[64,1641,153],{"class":126},[64,1643,1448],{"class":130},[64,1645,1646],{"class":74},"\"recalc\u002Fmonths_formulas.xlsx\"",[64,1648,162],{"class":130},[64,1650,1651],{"class":165},"data_only",[64,1653,153],{"class":126},[64,1655,231],{"class":171},[64,1657,1658],{"class":130},")[",[64,1660,1465],{"class":74},[64,1662,1663],{"class":130},"]\n",[64,1665,1667,1670,1672,1675,1677,1679,1681,1684,1686,1688,1690,1693,1695],{"class":66,"line":1666},15,[64,1668,1669],{"class":130},"vstack ",[64,1671,153],{"class":126},[64,1673,1674],{"class":130}," [[c.value ",[64,1676,521],{"class":126},[64,1678,853],{"class":130},[64,1680,527],{"class":126},[64,1682,1683],{"class":130}," row] ",[64,1685,521],{"class":126},[64,1687,535],{"class":130},[64,1689,527],{"class":126},[64,1691,1692],{"class":130}," ws[",[64,1694,1486],{"class":74},[64,1696,612],{"class":130},[64,1698,1700,1702,1705,1708,1711,1713,1716,1718],{"class":66,"line":1699},16,[64,1701,220],{"class":171},[64,1703,1704],{"class":130},"(",[64,1706,1707],{"class":74},"\"VSTACK rows:\"",[64,1709,1710],{"class":130},", vstack[",[64,1712,353],{"class":171},[64,1714,1715],{"class":130},":",[64,1717,384],{"class":171},[64,1719,1720],{"class":130},"])\n",[64,1722,1724,1726,1728,1731,1734,1737],{"class":66,"line":1723},17,[64,1725,220],{"class":171},[64,1727,1704],{"class":130},[64,1729,1730],{"class":74},"\"matches position-based stack:\"",[64,1732,1733],{"class":130},", vstack ",[64,1735,1736],{"class":126},"==",[64,1738,1739],{"class":130}," by_position.to_numpy().tolist())\n",[64,1741,1743,1745,1747,1750,1753,1755,1757,1759,1761,1763,1765,1767,1769,1771],{"class":66,"line":1742},18,[64,1744,220],{"class":171},[64,1746,1704],{"class":130},[64,1748,1749],{"class":74},"\"TAKE -2:\"",[64,1751,1752],{"class":130},", [[c.value ",[64,1754,521],{"class":126},[64,1756,853],{"class":130},[64,1758,527],{"class":126},[64,1760,1683],{"class":130},[64,1762,521],{"class":126},[64,1764,535],{"class":130},[64,1766,527],{"class":126},[64,1768,1692],{"class":130},[64,1770,1532],{"class":74},[64,1772,1773],{"class":130},"]])\n",[64,1775,1777,1779,1781,1784,1787,1790,1793,1796,1799,1802,1804,1807,1809,1812,1814,1817,1819,1822,1824,1827],{"class":66,"line":1776},19,[64,1778,220],{"class":171},[64,1780,1704],{"class":130},[64,1782,1783],{"class":74},"\"TOCOL first 6:\"",[64,1785,1786],{"class":130},", [ws[",[64,1788,1789],{"class":126},"f",[64,1791,1792],{"class":74},"\"A",[64,1794,1795],{"class":752},"{",[64,1797,1798],{"class":130},"i",[64,1800,1801],{"class":752},"}",[64,1803,749],{"class":74},[64,1805,1806],{"class":130},"].value ",[64,1808,521],{"class":126},[64,1810,1811],{"class":130}," i ",[64,1813,527],{"class":126},[64,1815,1816],{"class":171}," range",[64,1818,1704],{"class":130},[64,1820,1821],{"class":171},"8",[64,1823,162],{"class":130},[64,1825,1826],{"class":171},"14",[64,1828,1829],{"class":130},")])\n",[10,1831,1832,1833,1835,1836,767,1839,1842,1843,1845,1846,767,1848,1850,1851,767,1854,1857,1858,1861,1862,1865,1866,1869,1870,48],{},"The recalculated ",[14,1834,16],{}," rows for February are ",[14,1837,1838],{},"['North', 3, 7]",[14,1840,1841],{},"['East', 4, 4]"," — orders in the Sales column — and the whole block equals the position-based frame from Step 1, not the name-aligned ",[14,1844,492],{},". ",[14,1847,24],{},[14,1849,28],{}," match ",[14,1852,1853],{},"tail",[14,1855,1856],{},"ravel"," applied to that position-based frame — the last row is ",[14,1859,1860],{},"West, 5, 1"," there, while the name-aligned frame correctly shows West's sales as 1 and orders as 5. The array formulas are written as ",[14,1863,1864],{},"ArrayFormula"," objects with ",[14,1867,1868],{},"_xlfn."," names because these functions are recent additions; the reasons are explained in ",[44,1871,1873],{"href":1872},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-excel-formulas-in-python\u002Fwrite-legacy-array-formulas-with-openpyxl\u002F","Write Legacy Array Formulas (Ctrl+Shift+Enter) with openpyxl",[262,1875,271,1880,271,1883,271,1886,271,1889,271,1894,271,1905,271,1911,271,1915,271,1920,271,1923,271,1926,271,1933,271,1939,271,1943,271,1947,271,1951,271,1954,271,1957,271,1963,271,1967,271,1970,271,1974,271,1977,271,1980,271,1987,271,1992],{"viewBox":1876,"role":265,"ariaLabelledBy":1877,"xmlns":269,"style":986},"4 0 752 142",[1878,1879],"vs-check-t","vs-check-d",[273,1881,1882],{"id":1878},"Verifying the pandas translation against Excel's functions",[277,1884,1885],{"id":1879},"The same ranges are stacked by pandas and by VSTACK, CHOOSECOLS, TAKE and TOCOL formulas written into a workbook. LibreOffice recalculates the formulas and the results are compared with the pandas frames.",[281,1887],{"x":384,"y":212,"width":995,"height":1888,"fill":286},"142",[281,1890],{"x":999,"y":1000,"width":1891,"height":1892,"rx":1893,"fill":293,"stroke":294,"style":473},"153.0","110.5","12",[1895,1896,1898],"g",{"transform":1897},"translate(84.5,37.8) scale(1.000)",[1899,1900],"path",{"d":1901,"fill":1902,"stroke":1903,"style":1904},"M12 3c-4 0-4 1.6-4 3v2h4.2v1H6c-2 0-3 1.4-3 4s1 4 3 4h2v-2.6c0-1.6 1.3-2.9 2.9-2.9h4.2c1.3 0 2.4-1.1 2.4-2.4V6c0-1.6-1.8-3-5.5-3z M10 5.5h.01 M12 21c4 0 4-1.6 4-3v-2h-4.2v-1H18c2 0 3-1.4 3-4s-1-4-3-4h-2v2.6c0 1.6-1.3 2.9-2.9 2.9H8.9c-1.3 0-2.4 1.1-2.4 2.4V18c0 1.6 1.8 3 5.5 3z M14 18.5h.01","none","var(--brand-strong,#4338ca)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[297,1906,1910],{"x":1907,"y":1908,"style":1909},"96.5","84.2","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","pandas results",[297,1912,1914],{"x":1907,"y":1913,"style":1033},"103.8","concat, iloc, ravel",[66,1916],{"x1":1917,"y1":1918,"x2":1919,"y2":1918,"stroke":294,"style":473},"178.0","71.2","200.0",[475,1921],{"points":1922,"fill":478},"204.0,71.2 195.0,76.2 195.0,66.2",[281,1924],{"x":1925,"y":1000,"width":1891,"height":1892,"rx":1893,"fill":1023,"stroke":320,"style":473},"209.0",[1895,1927,1929],{"transform":1928},"translate(273.5,29.0) scale(1.000)",[1899,1930],{"d":1931,"fill":1902,"stroke":1932,"style":1904},"M6 3h9l4 4v14H6z M15 3v4h4 M9.5 11.5l4.5 6 M14 11.5l-4.5 6","var(--text,#172033)",[297,1934,1938],{"x":1935,"y":1936,"style":1937},"285.5","75.5","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Formulas in a",[297,1940,1942],{"x":1935,"y":1941,"style":1937},"93.0","sheet",[297,1944,1946],{"x":1935,"y":1945,"style":1033},"112.5","=_xlfn.VSTACK(…)",[66,1948],{"x1":1949,"y1":1918,"x2":1950,"y2":1918,"stroke":294,"style":473},"367.0","389.0",[475,1952],{"points":1953,"fill":478},"393.0,71.2 384.0,76.2 384.0,66.2",[281,1955],{"x":1956,"y":1000,"width":1891,"height":1892,"rx":1893,"fill":293,"stroke":294,"style":473},"398.0",[1895,1958,1960],{"transform":1959},"translate(462.5,37.8) scale(1.000)",[1899,1961],{"d":1962,"fill":1902,"stroke":1903,"style":1904},"M12 9a3 3 0 1 0 .01 0z M12 2.5v3 M12 18.5v3 M2.5 12h3 M18.5 12h3 M5.3 5.3l2.1 2.1 M16.6 16.6l2.1 2.1 M5.3 18.7l2.1-2.1 M16.6 7.4l2.1-2.1",[297,1964,1966],{"x":1965,"y":1908,"style":1909},"474.5","Recalculate",[297,1968,1969],{"x":1965,"y":1913,"style":1033},"soffice --convert-to",[66,1971],{"x1":1972,"y1":1918,"x2":1973,"y2":1918,"stroke":294,"style":473},"556.0","578.0",[475,1975],{"points":1976,"fill":478},"582.0,71.2 573.0,76.2 573.0,66.2",[281,1978],{"x":1979,"y":1000,"width":1891,"height":1892,"rx":1893,"fill":437,"stroke":438,"style":473},"587.0",[1895,1981,1983],{"transform":1982},"translate(651.5,37.8) scale(1.000)",[1899,1984],{"d":1985,"fill":1902,"stroke":1986,"style":1904},"M5 12.5l4.5 4.5L19 7","var(--teal-ink,#0b6157)",[297,1988,1991],{"x":1989,"y":1908,"style":1990},"663.5","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Compare",[297,1993,1994],{"x":1989,"y":1913,"style":1033},"position vs name",[50,1996,1998],{"id":1997},"performance-notes","Performance notes",[10,2000,2001,2002,2004,2005,2008,2009,2011,2012,2014,2015,2017],{},"All of these operations are cheap in pandas: ",[14,2003,492],{}," of a few dozen monthly sheets with tens of thousands of rows each takes milliseconds, and ",[14,2006,2007],{},"iloc"," selections and ",[14,2010,1856],{}," are views or single copies. The cost in a real job is reading the sheets, not reshaping them. In Excel, by contrast, a ",[14,2013,16],{}," over many large ranges recalculates on every change to any of them; moving that consolidation into Python and writing the result as values keeps big workbooks responsive. When stacking many files, collect the frames in a list and call ",[14,2016,492],{}," once — appending inside a loop copies the growing frame every time and turns a linear job into a quadratic one.",[50,2019,2021],{"id":2020},"common-pitfalls","Common pitfalls",[2023,2024,2025,2036,2048,2060,2070,2090],"ul",{},[2026,2027,2028,2032,2033,2035],"li",{},[2029,2030,2031],"strong",{},"Assuming concat stacks by position."," It aligns by column name; columns in a different order are matched, not swapped — usually what you want, but not what ",[14,2034,16],{}," does.",[2026,2037,2038,2041,2042,767,2044,2047],{},[2029,2039,2040],{},"Misspelled headers."," ",[14,2043,105],{},[14,2045,2046],{},"Sales "," are different names to pandas and become two half-empty columns; standardise names first.",[2026,2049,2050,2053,2054,763,2057,48],{},[2029,2051,2052],{},"Off-by-one indexes."," Excel's ",[14,2055,2056],{},"CHOOSECOLS(range, 1)",[14,2058,2059],{},"iloc[:, 0]",[2026,2061,2062,2065,2066,2069],{},[2029,2063,2064],{},"Expecting key matching from HSTACK or axis=1 concat."," Both line up rows by position or index; use ",[14,2067,2068],{},"merge"," for keys.",[2026,2071,2072,2079,2080,2082,2083,2085,2086,2089],{},[2029,2073,2074,2076,2077,48],{},[14,2075,679],{}," versus ",[14,2078,675],{}," Excel pads ragged stacks with ",[14,2081,679],{},"; pandas with ",[14,2084,675],{},", which ",[14,2087,2088],{},"fillna"," can replace.",[2026,2091,2092,2095,2096,2099,2100,2103],{},[2029,2093,2094],{},"Duplicate index labels after concat."," Each source keeps its own 0, 1, 2… index; pass ",[14,2097,2098],{},"ignore_index=True"," or call ",[14,2101,2102],{},"reset_index(drop=True)"," before selecting rows by label.",[50,2105,2107],{"id":2106},"conclusion","Conclusion",[10,2109,2110,767,2112,2114,2115,2117,2118,767,2120,2114,2123,162,2126,767,2128,162,2130,767,2132,2114,2135,2137,2138,767,2140,2142,2143,767,2145,2148,2149,2151],{},[14,2111,16],{},[14,2113,576],{}," are ",[14,2116,239],{}," along rows and columns, ",[14,2119,24],{},[14,2121,2122],{},"DROP",[14,2124,2125],{},"head",[14,2127,1853],{},[14,2129,2007],{},[14,2131,20],{},[14,2133,2134],{},"CHOOSEROWS",[14,2136,2007],{}," with Excel's 1-based positions converted, and ",[14,2139,28],{},[14,2141,1111],{}," are NumPy ",[14,2144,1856],{},[14,2146,2147],{},"reshape",". The difference to remember is alignment: Excel stacks by position, pandas by column name and index — which makes pandas safer when sheets disagree on column order, and means you must stack raw values when you need to match an existing ",[14,2150,16],{}," exactly.",[50,2153,2155],{"id":2154},"frequently-asked-questions","Frequently asked questions",[10,2157,2158,2161,2162,2165],{},[2029,2159,2160],{},"What is the pandas equivalent of Excel VSTACK?","\npd.concat(",[64,2163,2164],{},"df1, df2",") stacks DataFrames vertically. Unlike VSTACK, it matches columns by name rather than position, so sheets with the same columns in a different order are combined correctly.",[10,2167,2168,2171,2172,2178],{},[2029,2169,2170],{},"How do I do CHOOSECOLS in pandas?","\nSelect by name with df[[\"Region\", \"Orders\"]], or by position with df.iloc",[64,2173,2174,2175],{},":, ",[64,2176,2177],{},"0, 2",". Excel's positions start at 1, so subtract one; negative positions count from the end in both.",[10,2180,2181,2184,2185,2188,2189,48],{},[2029,2182,2183],{},"What replaces Excel TAKE and DROP in pandas?","\nTAKE(range, n) is df.head(n) and TAKE(range, -n) is df.tail(n). DROP(range, n) is df.iloc",[64,2186,2187],{},"n:"," and DROP(range, -n) is df.iloc",[64,2190,2191],{},":-n",[10,2193,2194,2197],{},[2029,2195,2196],{},"How do I flatten a range into one column like TOCOL?","\nUse df.to_numpy().ravel() to read row by row, which matches TOCOL's default, or ravel(order=\"F\") to read column by column. For data with headers, melt is usually more useful.",[50,2199,2201],{"id":2200},"related","Related",[2023,2203,2204,2210,2217,2224],{},[2026,2205,2206,2207,2209],{},"Up one level: ",[44,2208,47],{"href":46}," — Excel functions in pandas.",[2026,2211,2212,2216],{},[44,2213,2215],{"href":2214},"\u002Fadvanced-data-transformation-and-cleaning\u002Fmerging-and-joining-excel-dataframes\u002Fconcatenate-excel-sheets-with-different-columns\u002F","Concatenate Excel Sheets with Different Columns"," — stacking when the columns do not match.",[2026,2218,2219,2223],{},[44,2220,2222],{"href":2221},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Funique-sort-and-filter-equivalents-in-pandas\u002F","UNIQUE, SORT and FILTER Equivalents in pandas"," — the other dynamic array functions.",[2026,2225,2226,2230],{},[44,2227,2229],{"href":2228},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fread-all-sheets-from-an-excel-file-into-dataframes\u002F","Read All Sheets from an Excel File into DataFrames"," — loading the sheets to stack.",[2232,2233,2234],"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 .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 .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}",{"title":60,"searchDepth":140,"depth":140,"links":2236},[2237,2238,2239,2240,2241,2242,2243,2244,2245,2246,2247,2248],{"id":52,"depth":140,"text":53},{"id":113,"depth":140,"text":114},{"id":570,"depth":140,"text":571},{"id":690,"depth":140,"text":691},{"id":806,"depth":140,"text":807},{"id":1124,"depth":140,"text":1125},{"id":1396,"depth":140,"text":1397},{"id":1997,"depth":140,"text":1998},{"id":2020,"depth":140,"text":2021},{"id":2106,"depth":140,"text":2107},{"id":2154,"depth":140,"text":2155},{"id":2200,"depth":140,"text":2201},"2026-10-02","Translate Excel's array-shaping functions — VSTACK, HSTACK, TAKE, DROP, CHOOSECOLS, CHOOSEROWS, TOCOL and WRAPROWS — into pandas and NumPy, including the one difference that changes results: Excel stacks by position, pandas by column name and index. Each mapping is checked against the spreadsheet's own result.","md",[2253,2255,2257,2259],{"q":2160,"a":2254},"pd.concat([df1, df2]) stacks DataFrames vertically. Unlike VSTACK, it matches columns by name rather than position, so sheets with the same columns in a different order are combined correctly.",{"q":2170,"a":2256},"Select by name with df[[\"Region\", \"Orders\"]], or by position with df.iloc[:, [0, 2]]. Excel's positions start at 1, so subtract one; negative positions count from the end in both.",{"q":2183,"a":2258},"TAKE(range, n) is df.head(n) and TAKE(range, -n) is df.tail(n). DROP(range, n) is df.iloc[n:] and DROP(range, -n) is df.iloc[:-n].",{"q":2196,"a":2260},"Use df.to_numpy().ravel() to read row by row, which matches TOCOL's default, or ravel(order=\"F\") to read column by column. For data with headers, melt is usually more useful.","vstack hstack take and choosecols equivalents in pandas",null,{"breadcrumb":2264},[2265,2268,2271],{"name":2266,"item":2267},"Home","\u002F",{"name":2269,"item":2270},"Advanced Data Transformation and Cleaning for Excel Automation","\u002Fadvanced-data-transformation-and-cleaning\u002F",{"name":47,"item":46},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fvstack-hstack-take-and-choosecols-equivalents-in-pandas",{"title":2274,"description":2275},"Excel VSTACK, HSTACK, TAKE, CHOOSECOLS in pandas","pandas equivalents of VSTACK and HSTACK (concat by name vs position), TAKE and DROP (head, tail, iloc), CHOOSECOLS and CHOOSEROWS (1-based, negative indexes), TOCOL and WRAPROWS (NumPy reshape), with #N\u002FA padding compared and verified by recalculation.","vstack-hstack-take-and-choosecols-equivalents-in-pandas","advanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fvstack-hstack-take-and-choosecols-equivalents-in-pandas\u002Findex",[2279,2280],"formula-equivalents","pandas","how-to","mA-OFrf88C3PVeKURLwOiF9ks1nycm7a0pYai-m5b8I",[2284,2287],{"title":2222,"path":2285,"stem":2286,"children":-1},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Funique-sort-and-filter-equivalents-in-pandas","advanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Funique-sort-and-filter-equivalents-in-pandas\u002Findex",{"title":2288,"path":2289,"stem":2290,"children":-1},"XIRR and XNPV Equivalents in Python","\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fxirr-and-xnpv-equivalents-in-python","advanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fxirr-and-xnpv-equivalents-in-python\u002Findex",[2292,2294],{"path":2293,"title":47},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas",{"path":2295,"title":2269},"\u002Fadvanced-data-transformation-and-cleaning",[],[2298,2301,2304,2307,2310,2313],{"path":2299,"title":2300,"kind":2281},"\u002Fadvanced-data-transformation-and-cleaning\u002Fmerging-and-joining-excel-dataframes\u002Fvlookup-equivalent-in-pandas-for-excel-files","The VLOOKUP Equivalent in pandas for Excel Files",{"path":2302,"title":2303,"kind":2281},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fextract-numbers-and-codes-from-text-with-pandas","Extract Numbers and Codes from Text with pandas",{"path":2305,"title":2306,"kind":2281},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fsplit-full-names-into-first-and-last-names-with-pandas","Split Full Names into First and Last Names with pandas",{"path":2308,"title":2309,"kind":2281},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fbin-values-into-ranges-with-pandas-cut","Bin Values into Ranges Like Excel FREQUENCY with pd.cut",{"path":2311,"title":2312,"kind":2281},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fcalculate-percent-of-total-per-group-in-pandas","Calculate Percent of Total per Group in pandas",{"path":2314,"title":2315,"kind":2281},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fcount-distinct-values-per-group-in-pandas","Count Distinct Values per Group in pandas",1790972090698]