[{"data":1,"prerenderedAt":2439},["ShallowReactive",2],{"doc:\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fuse-different-aggregations-per-column-in-a-pivot":3,"surround:\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fuse-different-aggregations-per-column-in-a-pivot":2406,"ancestors:\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fuse-different-aggregations-per-column-in-a-pivot":2415,"children:\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fuse-different-aggregations-per-column-in-a-pivot":2420,"related:\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fuse-different-aggregations-per-column-in-a-pivot":2421},{"id":4,"title":5,"body":6,"dateModified":2372,"datePublished":2372,"description":2373,"extension":2374,"faq":2375,"keyword":2384,"kind":2385,"meta":2386,"navigation":469,"path":2395,"seo":2396,"slug":2399,"stem":2400,"topics":2401,"type":2404,"__hash__":2405},"docs\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fuse-different-aggregations-per-column-in-a-pivot\u002Findex.md","Use Different Aggregations per Column in a pandas Pivot",{"type":7,"value":8,"toc":2358},"minimark",[9,24,409,414,441,747,751,757,865,872,876,883,1022,1037,1164,1168,1174,1246,1249,1253,1256,1359,1374,1378,1385,1635,1649,1784,1788,1794,1961,1967,1971,1974,2217,2223,2227,2272,2276,2293,2297,2303,2309,2315,2321,2325,2354],[10,11,12,13,17,18,23],"p",{},"A useful summary rarely applies one function to everything. For each region you want total revenue, total units, the average and the weighted price, the number of distinct customers, and the dates of the first and last orders. Excel's pivot table lets you set \"Summarize value field by\" separately for each field; pandas does the same with an ",[14,15,16],"code",{},"aggfunc"," dictionary or, more readably, with named aggregation. This guide, part of ",[19,20,22],"a",{"href":21},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002F","Creating Pivot Tables from Excel Data",", shows both, the weighted-average trap, and a total row that follows the same rules as the groups.",[25,26,34,35,34,39,34,43,34,51,34,60,34,64,34,71,34,75,34,79,34,83,34,87,34,91,34,95,34,99,34,104,34,106,34,110,34,112,34,115,34,117,34,120,34,122,34,125,34,128,34,132,34,134,34,138,34,140,34,142,34,144,34,147,34,149,34,152,34,155,34,159,34,161,34,163,34,165,34,167,34,169,34,172,34,174,34,177,34,180,34,183,34,185,34,187,34,189,34,191,34,193,34,196,34,198,34,201,34,204,34,207,34,209,34,212,34,214,34,216,34,218,34,221,34,223,34,226,34,229,34,233,34,235,34,237,34,239,34,241,34,243,34,245,34,247,34,250,34,253,34,257,34,259,34,261,34,263,34,265,34,267,34,269,34,271,34,273,34,276,34,280,34,283,34,287,34,290,34,294,34,297,34,301,34,304,34,306,34,309,34,311,34,313,34,315,34,318,34,320,34,323,34,325,34,328,34,330,34,332,34,334,34,336,34,338,34,341,34,343,34,345,34,347,34,350,34,352,34,354,34,356,34,358,34,360,34,363,34,365,34,367,34,369,34,372,34,378,34,382,34,390,34,395,34,403],"svg",{"viewBox":27,"role":28,"ariaLabelledBy":29,"xmlns":32,"style":33},"4 0 752 276","img",[30,31],"ag-overview-t","ag-overview-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[36,37,38],"title",{"id":30},"One order list, a different rule for each summary column",[40,41,42],"desc",{"id":31},"Order rows with region, customer, date, units, price and revenue are summarised per region. Revenue and units are summed, customers are counted distinctly, the first and last order dates are taken with min and max, and the price is shown both as a simple and a weighted average.",[44,45],"rect",{"x":46,"y":47,"width":48,"height":49,"fill":50},"4","0","752","276","#ffffff",[44,52],{"x":53,"y":54,"width":55,"height":56,"rx":47,"fill":57,"stroke":58,"style":59},"20.0","40.0","32.0","24.0","#e7ebef","var(--line,#cdd5e6)","stroke-width:1px",[44,61],{"x":62,"y":54,"width":63,"height":56,"rx":47,"fill":57,"stroke":58,"style":59},"52.0","52.3",[65,66,70],"text",{"x":67,"y":68,"style":69},"78.2","57.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[44,72],{"x":73,"y":54,"width":74,"height":56,"rx":47,"fill":57,"stroke":58,"style":59},"104.3","66.4",[65,76,78],{"x":77,"y":68,"style":69},"137.5","B",[44,80],{"x":81,"y":54,"width":82,"height":56,"rx":47,"fill":57,"stroke":58,"style":59},"170.7","44.0",[65,84,86],{"x":85,"y":68,"style":69},"192.7","C",[44,88],{"x":89,"y":54,"width":90,"height":56,"rx":47,"fill":57,"stroke":58,"style":59},"214.8","43.6",[65,92,94],{"x":93,"y":68,"style":69},"236.6","D",[44,96],{"x":53,"y":97,"width":55,"height":98,"rx":47,"fill":57,"stroke":58,"style":59},"64.0","28.0",[65,100,103],{"x":101,"y":102,"style":69},"36.0","83.0","1",[44,105],{"x":62,"y":97,"width":63,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,107,109],{"x":67,"y":102,"style":108},"font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Region",[44,111],{"x":73,"y":97,"width":74,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,113,114],{"x":77,"y":102,"style":108},"Customer",[44,116],{"x":81,"y":97,"width":82,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,118,119],{"x":85,"y":102,"style":108},"Units",[44,121],{"x":89,"y":97,"width":90,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,123,124],{"x":93,"y":102,"style":108},"Price",[44,126],{"x":53,"y":127,"width":55,"height":98,"rx":47,"fill":57,"stroke":58,"style":59},"92.0",[65,129,131],{"x":101,"y":130,"style":69},"111.0","2",[44,133],{"x":62,"y":127,"width":63,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,135,137],{"x":67,"y":130,"style":136},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","North",[44,139],{"x":73,"y":127,"width":74,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,141,70],{"x":77,"y":130,"style":136},[44,143],{"x":81,"y":127,"width":82,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,145,146],{"x":85,"y":130,"style":136},"10",[44,148],{"x":89,"y":127,"width":90,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,150,151],{"x":93,"y":130,"style":136},"2.00",[44,153],{"x":53,"y":154,"width":55,"height":98,"rx":47,"fill":57,"stroke":58,"style":59},"120.0",[65,156,158],{"x":101,"y":157,"style":69},"139.0","3",[44,160],{"x":62,"y":154,"width":63,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,162,137],{"x":67,"y":157,"style":136},[44,164],{"x":73,"y":154,"width":74,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,166,78],{"x":77,"y":157,"style":136},[44,168],{"x":81,"y":154,"width":82,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,170,171],{"x":85,"y":157,"style":136},"5",[44,173],{"x":89,"y":154,"width":90,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,175,176],{"x":93,"y":157,"style":136},"3.00",[44,178],{"x":53,"y":179,"width":55,"height":98,"rx":47,"fill":57,"stroke":58,"style":59},"148.0",[65,181,46],{"x":101,"y":182,"style":69},"167.0",[44,184],{"x":62,"y":179,"width":63,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,186,137],{"x":67,"y":182,"style":136},[44,188],{"x":73,"y":179,"width":74,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,190,70],{"x":77,"y":182,"style":136},[44,192],{"x":81,"y":179,"width":82,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,194,195],{"x":85,"y":182,"style":136},"8",[44,197],{"x":89,"y":179,"width":90,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,199,200],{"x":93,"y":182,"style":136},"2.50",[44,202],{"x":53,"y":203,"width":55,"height":98,"rx":47,"fill":57,"stroke":58,"style":59},"176.0",[65,205,171],{"x":101,"y":206,"style":69},"195.0",[44,208],{"x":62,"y":203,"width":63,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,210,211],{"x":67,"y":206,"style":136},"South",[44,213],{"x":73,"y":203,"width":74,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,215,86],{"x":77,"y":206,"style":136},[44,217],{"x":81,"y":203,"width":82,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,219,220],{"x":85,"y":206,"style":136},"20",[44,222],{"x":89,"y":203,"width":90,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,224,225],{"x":93,"y":206,"style":136},"1.50",[44,227],{"x":53,"y":228,"width":55,"height":98,"rx":47,"fill":57,"stroke":58,"style":59},"204.0",[65,230,232],{"x":101,"y":231,"style":69},"223.0","6",[44,234],{"x":62,"y":228,"width":63,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,236,211],{"x":67,"y":231,"style":136},[44,238],{"x":73,"y":228,"width":74,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,240,70],{"x":77,"y":231,"style":136},[44,242],{"x":81,"y":228,"width":82,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,244,46],{"x":85,"y":231,"style":136},[44,246],{"x":89,"y":228,"width":90,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,248,249],{"x":93,"y":231,"style":136},"4.00",[44,251],{"x":53,"y":252,"width":55,"height":98,"rx":47,"fill":57,"stroke":58,"style":59},"232.0",[65,254,256],{"x":101,"y":255,"style":69},"251.0","7",[44,258],{"x":62,"y":252,"width":63,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,260,211],{"x":67,"y":255,"style":136},[44,262],{"x":73,"y":252,"width":74,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,264,94],{"x":77,"y":255,"style":136},[44,266],{"x":81,"y":252,"width":82,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,268,232],{"x":85,"y":255,"style":136},[44,270],{"x":89,"y":252,"width":90,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,272,176],{"x":93,"y":255,"style":136},[44,274],{"x":275,"y":54,"width":55,"height":56,"rx":47,"fill":57,"stroke":58,"style":59},"450.6",[44,277],{"x":278,"y":54,"width":279,"height":56,"rx":47,"fill":57,"stroke":58,"style":59},"482.6","52.6",[65,281,70],{"x":282,"y":68,"style":69},"508.9",[44,284],{"x":285,"y":54,"width":286,"height":56,"rx":47,"fill":57,"stroke":58,"style":59},"535.2","59.1",[65,288,78],{"x":289,"y":68,"style":69},"564.7",[44,291],{"x":292,"y":54,"width":293,"height":56,"rx":47,"fill":57,"stroke":58,"style":59},"594.3","70.8",[65,295,86],{"x":296,"y":68,"style":69},"629.7",[44,298],{"x":299,"y":54,"width":300,"height":56,"rx":47,"fill":57,"stroke":58,"style":59},"665.1","74.9",[65,302,94],{"x":303,"y":68,"style":69},"702.6",[44,305],{"x":275,"y":97,"width":55,"height":98,"rx":47,"fill":57,"stroke":58,"style":59},[65,307,103],{"x":308,"y":102,"style":69},"466.6",[44,310],{"x":278,"y":97,"width":279,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,312,109],{"x":282,"y":102,"style":108},[44,314],{"x":285,"y":97,"width":286,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,316,317],{"x":289,"y":102,"style":108},"revenue",[44,319],{"x":292,"y":97,"width":293,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,321,322],{"x":296,"y":102,"style":108},"customers",[44,324],{"x":299,"y":97,"width":300,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,326,327],{"x":303,"y":102,"style":108},"wavg_price",[44,329],{"x":275,"y":127,"width":55,"height":98,"rx":47,"fill":57,"stroke":58,"style":59},[65,331,131],{"x":308,"y":130,"style":69},[44,333],{"x":278,"y":127,"width":279,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,335,137],{"x":282,"y":130,"style":136},[44,337],{"x":285,"y":127,"width":286,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,339,340],{"x":289,"y":130,"style":136},"55.00",[44,342],{"x":292,"y":127,"width":293,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,344,131],{"x":296,"y":130,"style":136},[44,346],{"x":299,"y":127,"width":300,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,348,349],{"x":303,"y":130,"style":136},"2.39",[44,351],{"x":275,"y":154,"width":55,"height":98,"rx":47,"fill":57,"stroke":58,"style":59},[65,353,158],{"x":308,"y":157,"style":69},[44,355],{"x":278,"y":154,"width":279,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,357,211],{"x":282,"y":157,"style":136},[44,359],{"x":285,"y":154,"width":286,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,361,362],{"x":289,"y":157,"style":136},"64.00",[44,364],{"x":292,"y":154,"width":293,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,366,158],{"x":296,"y":157,"style":136},[44,368],{"x":299,"y":154,"width":300,"height":98,"rx":47,"fill":50,"stroke":58,"style":59},[65,370,371],{"x":303,"y":157,"style":136},"2.13",[65,373,377],{"x":374,"y":375,"style":376},"139.2","29.0","font-size:12.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","before",[65,379,381],{"x":380,"y":375,"style":376},"595.3","after",[383,384],"line",{"x1":385,"y1":386,"x2":387,"y2":386,"stroke":388,"style":389},"268.4","94.0","436.6","var(--brand,#5b5cf0)","stroke-width:2px",[391,392],"polygon",{"points":393,"fill":394},"440.6,94.0 431.6,99.0 431.6,89.0","#5b5cf0",[44,396],{"x":397,"y":398,"width":399,"height":400,"rx":401,"fill":50,"stroke":58,"style":402},"293.6","61.0","121.8","22.0","11","stroke-width:1.2px",[65,404,408],{"x":405,"y":406,"style":407},"354.5","76.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","agg per column",[410,411,413],"h2",{"id":412},"prerequisites","Prerequisites",[415,416,421],"pre",{"className":417,"code":418,"language":419,"meta":420,"style":420},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas openpyxl\n","bash","",[14,422,423],{"__ignoreMap":420},[424,425,427,431,435,438],"span",{"class":383,"line":426},1,[424,428,430],{"class":429},"sMTad","pip",[424,432,434],{"class":433},"srMev"," install",[424,436,437],{"class":433}," pandas",[424,439,440],{"class":433}," openpyxl\n",[415,442,446],{"className":443,"code":444,"language":445,"meta":420,"style":420},"language-python shiki shiki-themes github-light github-dark-high-contrast","import pandas as pd\n\norders = pd.DataFrame({\n    \"Region\": [\"North\", \"North\", \"North\", \"South\", \"South\", \"South\"],\n    \"Customer\": [\"A\", \"B\", \"A\", \"C\", \"A\", \"D\"],\n    \"Date\": pd.to_datetime([\"2026-01-05\", \"2026-02-10\", \"2026-03-01\",\n                            \"2026-01-20\", \"2026-02-02\", \"2026-03-15\"]),\n    \"Units\": [10, 5, 8, 20, 4, 6],\n    \"Price\": [2.0, 3.0, 2.5, 1.5, 4.0, 3.0],\n})\norders[\"Revenue\"] = orders[\"Units\"] * orders[\"Price\"]\norders.to_excel(\"orders.xlsx\", index=False)\ndf = pd.read_excel(\"orders.xlsx\")\n","python",[14,447,448,464,471,483,520,556,581,600,633,670,676,709,732],{"__ignoreMap":420},[424,449,450,454,458,461],{"class":383,"line":426},[424,451,453],{"class":452},"s-kum","import",[424,455,457],{"class":456},"skGVy"," pandas ",[424,459,460],{"class":452},"as",[424,462,463],{"class":456}," pd\n",[424,465,467],{"class":383,"line":466},2,[424,468,470],{"emptyLinePlaceholder":469},true,"\n",[424,472,474,477,480],{"class":383,"line":473},3,[424,475,476],{"class":456},"orders ",[424,478,479],{"class":452},"=",[424,481,482],{"class":456}," pd.DataFrame({\n",[424,484,486,489,492,495,498,500,502,504,506,509,511,513,515,517],{"class":383,"line":485},4,[424,487,488],{"class":433},"    \"Region\"",[424,490,491],{"class":456},": [",[424,493,494],{"class":433},"\"North\"",[424,496,497],{"class":456},", ",[424,499,494],{"class":433},[424,501,497],{"class":456},[424,503,494],{"class":433},[424,505,497],{"class":456},[424,507,508],{"class":433},"\"South\"",[424,510,497],{"class":456},[424,512,508],{"class":433},[424,514,497],{"class":456},[424,516,508],{"class":433},[424,518,519],{"class":456},"],\n",[424,521,523,526,528,531,533,536,538,540,542,545,547,549,551,554],{"class":383,"line":522},5,[424,524,525],{"class":433},"    \"Customer\"",[424,527,491],{"class":456},[424,529,530],{"class":433},"\"A\"",[424,532,497],{"class":456},[424,534,535],{"class":433},"\"B\"",[424,537,497],{"class":456},[424,539,530],{"class":433},[424,541,497],{"class":456},[424,543,544],{"class":433},"\"C\"",[424,546,497],{"class":456},[424,548,530],{"class":433},[424,550,497],{"class":456},[424,552,553],{"class":433},"\"D\"",[424,555,519],{"class":456},[424,557,559,562,565,568,570,573,575,578],{"class":383,"line":558},6,[424,560,561],{"class":433},"    \"Date\"",[424,563,564],{"class":456},": pd.to_datetime([",[424,566,567],{"class":433},"\"2026-01-05\"",[424,569,497],{"class":456},[424,571,572],{"class":433},"\"2026-02-10\"",[424,574,497],{"class":456},[424,576,577],{"class":433},"\"2026-03-01\"",[424,579,580],{"class":456},",\n",[424,582,584,587,589,592,594,597],{"class":383,"line":583},7,[424,585,586],{"class":433},"                            \"2026-01-20\"",[424,588,497],{"class":456},[424,590,591],{"class":433},"\"2026-02-02\"",[424,593,497],{"class":456},[424,595,596],{"class":433},"\"2026-03-15\"",[424,598,599],{"class":456},"]),\n",[424,601,603,606,608,611,613,615,617,619,621,623,625,627,629,631],{"class":383,"line":602},8,[424,604,605],{"class":433},"    \"Units\"",[424,607,491],{"class":456},[424,609,146],{"class":610},"sP0c6",[424,612,497],{"class":456},[424,614,171],{"class":610},[424,616,497],{"class":456},[424,618,195],{"class":610},[424,620,497],{"class":456},[424,622,220],{"class":610},[424,624,497],{"class":456},[424,626,46],{"class":610},[424,628,497],{"class":456},[424,630,232],{"class":610},[424,632,519],{"class":456},[424,634,636,639,641,644,646,649,651,654,656,659,661,664,666,668],{"class":383,"line":635},9,[424,637,638],{"class":433},"    \"Price\"",[424,640,491],{"class":456},[424,642,643],{"class":610},"2.0",[424,645,497],{"class":456},[424,647,648],{"class":610},"3.0",[424,650,497],{"class":456},[424,652,653],{"class":610},"2.5",[424,655,497],{"class":456},[424,657,658],{"class":610},"1.5",[424,660,497],{"class":456},[424,662,663],{"class":610},"4.0",[424,665,497],{"class":456},[424,667,648],{"class":610},[424,669,519],{"class":456},[424,671,673],{"class":383,"line":672},10,[424,674,675],{"class":456},"})\n",[424,677,679,682,685,688,690,693,696,698,701,703,706],{"class":383,"line":678},11,[424,680,681],{"class":456},"orders[",[424,683,684],{"class":433},"\"Revenue\"",[424,686,687],{"class":456},"] ",[424,689,479],{"class":452},[424,691,692],{"class":456}," orders[",[424,694,695],{"class":433},"\"Units\"",[424,697,687],{"class":456},[424,699,700],{"class":452},"*",[424,702,692],{"class":456},[424,704,705],{"class":433},"\"Price\"",[424,707,708],{"class":456},"]\n",[424,710,712,715,718,720,724,726,729],{"class":383,"line":711},12,[424,713,714],{"class":456},"orders.to_excel(",[424,716,717],{"class":433},"\"orders.xlsx\"",[424,719,497],{"class":456},[424,721,723],{"class":722},"sa561","index",[424,725,479],{"class":452},[424,727,728],{"class":610},"False",[424,730,731],{"class":456},")\n",[424,733,735,738,740,743,745],{"class":383,"line":734},13,[424,736,737],{"class":456},"df ",[424,739,479],{"class":452},[424,741,742],{"class":456}," pd.read_excel(",[424,744,717],{"class":433},[424,746,731],{"class":456},[410,748,750],{"id":749},"step-1-an-aggfunc-dictionary-in-pivot_table","Step 1 — An aggfunc dictionary in pivot_table",[10,752,753,756],{},[14,754,755],{},"pivot_table"," accepts a dictionary that maps each value column to its function. A list applies several functions to one column:",[415,758,760],{"className":443,"code":759,"language":445,"meta":420,"style":420},"pt = df.pivot_table(index=\"Region\", values=[\"Revenue\", \"Units\", \"Price\"],\n                    aggfunc={\"Revenue\": \"sum\", \"Units\": [\"sum\", \"max\"], \"Price\": \"mean\"})\nprint(pt)\nprint(pt.columns.tolist())\n# [('Price', 'mean'), ('Revenue', 'sum'), ('Units', 'max'), ('Units', 'sum')]\n",[14,761,762,801,844,852,859],{"__ignoreMap":420},[424,763,764,767,769,772,774,776,779,781,784,786,789,791,793,795,797,799],{"class":383,"line":426},[424,765,766],{"class":456},"pt ",[424,768,479],{"class":452},[424,770,771],{"class":456}," df.pivot_table(",[424,773,723],{"class":722},[424,775,479],{"class":452},[424,777,778],{"class":433},"\"Region\"",[424,780,497],{"class":456},[424,782,783],{"class":722},"values",[424,785,479],{"class":452},[424,787,788],{"class":456},"[",[424,790,684],{"class":433},[424,792,497],{"class":456},[424,794,695],{"class":433},[424,796,497],{"class":456},[424,798,705],{"class":433},[424,800,519],{"class":456},[424,802,803,806,808,811,813,816,819,821,823,825,827,829,832,835,837,839,842],{"class":383,"line":466},[424,804,805],{"class":722},"                    aggfunc",[424,807,479],{"class":452},[424,809,810],{"class":456},"{",[424,812,684],{"class":433},[424,814,815],{"class":456},": ",[424,817,818],{"class":433},"\"sum\"",[424,820,497],{"class":456},[424,822,695],{"class":433},[424,824,491],{"class":456},[424,826,818],{"class":433},[424,828,497],{"class":456},[424,830,831],{"class":433},"\"max\"",[424,833,834],{"class":456},"], ",[424,836,705],{"class":433},[424,838,815],{"class":456},[424,840,841],{"class":433},"\"mean\"",[424,843,675],{"class":456},[424,845,846,849],{"class":383,"line":473},[424,847,848],{"class":610},"print",[424,850,851],{"class":456},"(pt)\n",[424,853,854,856],{"class":383,"line":485},[424,855,848],{"class":610},[424,857,858],{"class":456},"(pt.columns.tolist())\n",[424,860,861],{"class":383,"line":522},[424,862,864],{"class":863},"s-wDw","# [('Price', 'mean'), ('Revenue', 'sum'), ('Units', 'max'), ('Units', 'sum')]\n",[10,866,867,868,871],{},"This works, and it is the closest match to Excel's value fields. Two things make it awkward in reports: the columns come back sorted alphabetically rather than in the order you listed them, and they have two levels — ",[14,869,870],{},"('Units', 'max')"," — which must be flattened before writing a clean sheet.",[410,873,875],{"id":874},"step-2-named-aggregation-with-groupby","Step 2 — Named aggregation with groupby",[10,877,878,879,882],{},"When there is no column dimension — one row per region, no months across the top — ",[14,880,881],{},"groupby().agg()"," with named aggregation is clearer. Each keyword is the output column name, each value a pair of source column and function:",[415,884,886],{"className":443,"code":885,"language":445,"meta":420,"style":420},"summary = df.groupby(\"Region\").agg(\n    revenue=(\"Revenue\", \"sum\"),\n    units=(\"Units\", \"sum\"),\n    customers=(\"Customer\", \"nunique\"),\n    first_order=(\"Date\", \"min\"),\n    last_order=(\"Date\", \"max\"),\n    avg_price=(\"Price\", \"mean\"),\n)\nprint(summary)\n",[14,887,888,903,922,939,958,977,994,1011,1015],{"__ignoreMap":420},[424,889,890,893,895,898,900],{"class":383,"line":426},[424,891,892],{"class":456},"summary ",[424,894,479],{"class":452},[424,896,897],{"class":456}," df.groupby(",[424,899,778],{"class":433},[424,901,902],{"class":456},").agg(\n",[424,904,905,908,910,913,915,917,919],{"class":383,"line":466},[424,906,907],{"class":722},"    revenue",[424,909,479],{"class":452},[424,911,912],{"class":456},"(",[424,914,684],{"class":433},[424,916,497],{"class":456},[424,918,818],{"class":433},[424,920,921],{"class":456},"),\n",[424,923,924,927,929,931,933,935,937],{"class":383,"line":473},[424,925,926],{"class":722},"    units",[424,928,479],{"class":452},[424,930,912],{"class":456},[424,932,695],{"class":433},[424,934,497],{"class":456},[424,936,818],{"class":433},[424,938,921],{"class":456},[424,940,941,944,946,948,951,953,956],{"class":383,"line":485},[424,942,943],{"class":722},"    customers",[424,945,479],{"class":452},[424,947,912],{"class":456},[424,949,950],{"class":433},"\"Customer\"",[424,952,497],{"class":456},[424,954,955],{"class":433},"\"nunique\"",[424,957,921],{"class":456},[424,959,960,963,965,967,970,972,975],{"class":383,"line":522},[424,961,962],{"class":722},"    first_order",[424,964,479],{"class":452},[424,966,912],{"class":456},[424,968,969],{"class":433},"\"Date\"",[424,971,497],{"class":456},[424,973,974],{"class":433},"\"min\"",[424,976,921],{"class":456},[424,978,979,982,984,986,988,990,992],{"class":383,"line":558},[424,980,981],{"class":722},"    last_order",[424,983,479],{"class":452},[424,985,912],{"class":456},[424,987,969],{"class":433},[424,989,497],{"class":456},[424,991,831],{"class":433},[424,993,921],{"class":456},[424,995,996,999,1001,1003,1005,1007,1009],{"class":383,"line":583},[424,997,998],{"class":722},"    avg_price",[424,1000,479],{"class":452},[424,1002,912],{"class":456},[424,1004,705],{"class":433},[424,1006,497],{"class":456},[424,1008,841],{"class":433},[424,1010,921],{"class":456},[424,1012,1013],{"class":383,"line":602},[424,1014,731],{"class":456},[424,1016,1017,1019],{"class":383,"line":635},[424,1018,848],{"class":610},[424,1020,1021],{"class":456},"(summary)\n",[10,1023,1024,1025,1028,1029,1032,1033,1036],{},"The columns appear in the order written, with the names you chose, in a single level. ",[14,1026,1027],{},"nunique"," answers \"how many different customers\", which a pivot count of rows cannot: North has three orders but only two customers. ",[14,1030,1031],{},"min"," and ",[14,1034,1035],{},"max"," on dates give the first and last order without sorting.",[25,1038,34,1043,34,1046,34,1049,34,1052,34,1056,34,1061,34,1067,34,1070,34,1074,34,1078,34,1083,34,1085,34,1090,34,1092,34,1095,34,1098,34,1102,34,1104,34,1106,34,1108,34,1111,34,1114,34,1118,34,1120,34,1124,34,1126,34,1129,34,1132,34,1136,34,1138,34,1142,34,1144,34,1147,34,1150,34,1154,34,1156,34,1160,34,1162],{"viewBox":1039,"role":28,"ariaLabelledBy":1040,"xmlns":32,"style":33},"4 0 752 242",[1041,1042],"ag-funcs-t","ag-funcs-d",[36,1044,1045],{"id":1041},"Which function answers which question",[40,1047,1048],{"id":1042},"sum answers how much in total, mean answers what a typical row looks like, nunique answers how many different values, min and max on dates answer when something first and last happened, and count answers how many rows have a value.",[44,1050],{"x":46,"y":47,"width":48,"height":1051,"fill":50},"242",[44,1053],{"x":53,"y":1054,"width":1055,"height":54,"rx":47,"fill":50,"stroke":58,"style":59},"16.0","234.2",[44,1057],{"x":1058,"y":1054,"width":1059,"height":54,"rx":47,"fill":1060,"stroke":388,"style":402},"254.2","242.9","#f0f4ff",[65,1062,1066],{"x":1063,"y":1064,"style":1065},"375.7","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Function",[44,1068],{"x":1069,"y":1054,"width":1059,"height":54,"rx":47,"fill":1060,"stroke":388,"style":402},"497.1",[65,1071,1073],{"x":1072,"y":1064,"style":1065},"618.6","North example",[44,1075],{"x":53,"y":1076,"width":1055,"height":1077,"rx":47,"fill":57,"stroke":58,"style":59},"56.0","34.0",[65,1079,1082],{"x":55,"y":1080,"style":1081},"78.0","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start","How much in total?",[44,1084],{"x":1058,"y":1076,"width":1059,"height":1077,"rx":47,"fill":50,"stroke":58,"style":59},[65,1086,1089],{"x":1063,"y":1087,"style":1088},"77.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","sum",[44,1091],{"x":1069,"y":1076,"width":1059,"height":1077,"rx":47,"fill":50,"stroke":58,"style":59},[65,1093,1094],{"x":1072,"y":1087,"style":1088},"revenue 55.00",[44,1096],{"x":53,"y":1097,"width":1055,"height":1077,"rx":47,"fill":57,"stroke":58,"style":59},"90.0",[65,1099,1101],{"x":55,"y":1100,"style":1081},"112.0","How many different customers?",[44,1103],{"x":1058,"y":1097,"width":1059,"height":1077,"rx":47,"fill":50,"stroke":58,"style":59},[65,1105,1027],{"x":1063,"y":130,"style":1088},[44,1107],{"x":1069,"y":1097,"width":1059,"height":1077,"rx":47,"fill":50,"stroke":58,"style":59},[65,1109,1110],{"x":1072,"y":130,"style":1088},"2 (from 3 orders)",[44,1112],{"x":53,"y":1113,"width":1055,"height":1077,"rx":47,"fill":57,"stroke":58,"style":59},"124.0",[65,1115,1117],{"x":55,"y":1116,"style":1081},"146.0","When was the latest order?",[44,1119],{"x":1058,"y":1113,"width":1059,"height":1077,"rx":47,"fill":50,"stroke":58,"style":59},[65,1121,1123],{"x":1063,"y":1122,"style":1088},"145.0","max on Date",[44,1125],{"x":1069,"y":1113,"width":1059,"height":1077,"rx":47,"fill":50,"stroke":58,"style":59},[65,1127,1128],{"x":1072,"y":1122,"style":1088},"2026-03-01",[44,1130],{"x":53,"y":1131,"width":1055,"height":1077,"rx":47,"fill":57,"stroke":58,"style":59},"158.0",[65,1133,1135],{"x":55,"y":1134,"style":1081},"180.0","What does a typical order cost?",[44,1137],{"x":1058,"y":1131,"width":1059,"height":1077,"rx":47,"fill":50,"stroke":58,"style":59},[65,1139,1141],{"x":1063,"y":1140,"style":1088},"179.0","mean",[44,1143],{"x":1069,"y":1131,"width":1059,"height":1077,"rx":47,"fill":50,"stroke":58,"style":59},[65,1145,1146],{"x":1072,"y":1140,"style":1088},"price 2.50",[44,1148],{"x":53,"y":1149,"width":1055,"height":1077,"rx":47,"fill":57,"stroke":58,"style":59},"192.0",[65,1151,1153],{"x":55,"y":1152,"style":1081},"214.0","How many rows have a value?",[44,1155],{"x":1058,"y":1149,"width":1059,"height":1077,"rx":47,"fill":50,"stroke":58,"style":59},[65,1157,1159],{"x":1063,"y":1158,"style":1088},"213.0","count",[44,1161],{"x":1069,"y":1149,"width":1059,"height":1077,"rx":47,"fill":50,"stroke":58,"style":59},[65,1163,158],{"x":1072,"y":1158,"style":1088},[410,1165,1167],{"id":1166},"step-3-weighted-averages-are-a-ratio-not-a-mean","Step 3 — Weighted averages are a ratio, not a mean",[10,1169,1170,1173],{},[14,1171,1172],{},"avg_price"," is the plain mean of the price column: every order counts equally, whether it was for 5 units or 20. The average price actually paid per unit is total revenue divided by total units. Compute it from sums after aggregating:",[415,1175,1177],{"className":443,"code":1176,"language":445,"meta":420,"style":420},"summary[\"wavg_price\"] = summary[\"revenue\"] \u002F summary[\"units\"]\nprint(summary[[\"avg_price\", \"wavg_price\"]].round(3))\n#         avg_price  wavg_price\n# North       2.500       2.391\n# South       2.833       2.133\n",[14,1178,1179,1209,1231,1236,1241],{"__ignoreMap":420},[424,1180,1181,1184,1187,1189,1191,1194,1197,1199,1202,1204,1207],{"class":383,"line":426},[424,1182,1183],{"class":456},"summary[",[424,1185,1186],{"class":433},"\"wavg_price\"",[424,1188,687],{"class":456},[424,1190,479],{"class":452},[424,1192,1193],{"class":456}," summary[",[424,1195,1196],{"class":433},"\"revenue\"",[424,1198,687],{"class":456},[424,1200,1201],{"class":452},"\u002F",[424,1203,1193],{"class":456},[424,1205,1206],{"class":433},"\"units\"",[424,1208,708],{"class":456},[424,1210,1211,1213,1216,1219,1221,1223,1226,1228],{"class":383,"line":466},[424,1212,848],{"class":610},[424,1214,1215],{"class":456},"(summary[[",[424,1217,1218],{"class":433},"\"avg_price\"",[424,1220,497],{"class":456},[424,1222,1186],{"class":433},[424,1224,1225],{"class":456},"]].round(",[424,1227,158],{"class":610},[424,1229,1230],{"class":456},"))\n",[424,1232,1233],{"class":383,"line":473},[424,1234,1235],{"class":863},"#         avg_price  wavg_price\n",[424,1237,1238],{"class":383,"line":485},[424,1239,1240],{"class":863},"# North       2.500       2.391\n",[424,1242,1243],{"class":383,"line":522},[424,1244,1245],{"class":863},"# South       2.833       2.133\n",[10,1247,1248],{},"In South, the large 20-unit order at 1.50 pulls the true average well below the plain mean. The same rule covers every ratio in a report — margin percentage, conversion rate, cost per unit: sum the numerator and the denominator per group, then divide. Averaging a column of ratios is almost never what a reader expects.",[410,1250,1252],{"id":1251},"step-4-custom-functions-for-counts-with-a-condition","Step 4 — Custom functions for counts with a condition",[10,1254,1255],{},"Named aggregation accepts any function that takes a Series and returns one value. Count large orders or sum only one kind of value without adding helper columns:",[415,1257,1259],{"className":443,"code":1258,"language":445,"meta":420,"style":420},"extra = df.groupby(\"Region\").agg(\n    large_orders=(\"Units\", lambda s: (s >= 10).sum()),\n    repeat_customers=(\"Customer\", lambda s: (s.value_counts() > 1).sum()),\n)\nprint(extra)\n#         large_orders  repeat_customers\n# Region\n# North              1                 1\n# South              1                 0\n",[14,1260,1261,1274,1302,1328,1332,1339,1344,1349,1354],{"__ignoreMap":420},[424,1262,1263,1266,1268,1270,1272],{"class":383,"line":426},[424,1264,1265],{"class":456},"extra ",[424,1267,479],{"class":452},[424,1269,897],{"class":456},[424,1271,778],{"class":433},[424,1273,902],{"class":456},[424,1275,1276,1279,1281,1283,1285,1287,1290,1293,1296,1299],{"class":383,"line":466},[424,1277,1278],{"class":722},"    large_orders",[424,1280,479],{"class":452},[424,1282,912],{"class":456},[424,1284,695],{"class":433},[424,1286,497],{"class":456},[424,1288,1289],{"class":452},"lambda",[424,1291,1292],{"class":456}," s: (s ",[424,1294,1295],{"class":452},">=",[424,1297,1298],{"class":610}," 10",[424,1300,1301],{"class":456},").sum()),\n",[424,1303,1304,1307,1309,1311,1313,1315,1317,1320,1323,1326],{"class":383,"line":473},[424,1305,1306],{"class":722},"    repeat_customers",[424,1308,479],{"class":452},[424,1310,912],{"class":456},[424,1312,950],{"class":433},[424,1314,497],{"class":456},[424,1316,1289],{"class":452},[424,1318,1319],{"class":456}," s: (s.value_counts() ",[424,1321,1322],{"class":452},">",[424,1324,1325],{"class":610}," 1",[424,1327,1301],{"class":456},[424,1329,1330],{"class":383,"line":485},[424,1331,731],{"class":456},[424,1333,1334,1336],{"class":383,"line":522},[424,1335,848],{"class":610},[424,1337,1338],{"class":456},"(extra)\n",[424,1340,1341],{"class":383,"line":558},[424,1342,1343],{"class":863},"#         large_orders  repeat_customers\n",[424,1345,1346],{"class":383,"line":583},[424,1347,1348],{"class":863},"# Region\n",[424,1350,1351],{"class":383,"line":602},[424,1352,1353],{"class":863},"# North              1                 1\n",[424,1355,1356],{"class":383,"line":635},[424,1357,1358],{"class":863},"# South              1                 0\n",[10,1360,1361,1362,1365,1366,1368,1369,1373],{},"Lambdas are convenient but slow on large frames, because pandas calls them once per group in Python. For big data, build a boolean column first — ",[14,1363,1364],{},"df[\"large\"] = df[\"Units\"] >= 10"," — and aggregate it with ",[14,1367,818],{},", which runs vectorised. Conditional counting in general is covered in ",[19,1370,1372],{"href":1371},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fcountif-and-countifs-equivalent-in-pandas\u002F","COUNTIF and COUNTIFS Equivalent in pandas",".",[410,1375,1377],{"id":1376},"step-5-a-total-row-that-follows-the-same-rules","Step 5 — A total row that follows the same rules",[10,1379,1380,1381,1384],{},"Adding ",[14,1382,1383],{},"summary.sum()"," as a total row would add up the distinct customer counts (a customer active in two regions counted twice), sum the average prices and fail on dates. Instead, run the same aggregation over the whole frame:",[415,1386,1388],{"className":443,"code":1387,"language":445,"meta":420,"style":420},"RULES = dict(\n    revenue=(\"Revenue\", \"sum\"),\n    units=(\"Units\", \"sum\"),\n    customers=(\"Customer\", \"nunique\"),\n    first_order=(\"Date\", \"min\"),\n    last_order=(\"Date\", \"max\"),\n)\n\ndef summarise(frame, by):\n    out = frame.groupby(by).agg(**RULES)\n    out[\"wavg_price\"] = out[\"revenue\"] \u002F out[\"units\"]\n    return out\n\nby_region = summarise(df, \"Region\")\ntotal = summarise(df.assign(Region=\"Total\"), \"Region\")\nreport = pd.concat([by_region, total])\nprint(report[[\"revenue\", \"customers\", \"wavg_price\"]].round(2))\n",[14,1389,1390,1404,1420,1436,1452,1468,1484,1488,1492,1504,1521,1547,1555,1559,1574,1599,1610],{"__ignoreMap":420},[424,1391,1392,1395,1398,1401],{"class":383,"line":426},[424,1393,1394],{"class":610},"RULES",[424,1396,1397],{"class":452}," =",[424,1399,1400],{"class":610}," dict",[424,1402,1403],{"class":456},"(\n",[424,1405,1406,1408,1410,1412,1414,1416,1418],{"class":383,"line":466},[424,1407,907],{"class":722},[424,1409,479],{"class":452},[424,1411,912],{"class":456},[424,1413,684],{"class":433},[424,1415,497],{"class":456},[424,1417,818],{"class":433},[424,1419,921],{"class":456},[424,1421,1422,1424,1426,1428,1430,1432,1434],{"class":383,"line":473},[424,1423,926],{"class":722},[424,1425,479],{"class":452},[424,1427,912],{"class":456},[424,1429,695],{"class":433},[424,1431,497],{"class":456},[424,1433,818],{"class":433},[424,1435,921],{"class":456},[424,1437,1438,1440,1442,1444,1446,1448,1450],{"class":383,"line":485},[424,1439,943],{"class":722},[424,1441,479],{"class":452},[424,1443,912],{"class":456},[424,1445,950],{"class":433},[424,1447,497],{"class":456},[424,1449,955],{"class":433},[424,1451,921],{"class":456},[424,1453,1454,1456,1458,1460,1462,1464,1466],{"class":383,"line":522},[424,1455,962],{"class":722},[424,1457,479],{"class":452},[424,1459,912],{"class":456},[424,1461,969],{"class":433},[424,1463,497],{"class":456},[424,1465,974],{"class":433},[424,1467,921],{"class":456},[424,1469,1470,1472,1474,1476,1478,1480,1482],{"class":383,"line":558},[424,1471,981],{"class":722},[424,1473,479],{"class":452},[424,1475,912],{"class":456},[424,1477,969],{"class":433},[424,1479,497],{"class":456},[424,1481,831],{"class":433},[424,1483,921],{"class":456},[424,1485,1486],{"class":383,"line":583},[424,1487,731],{"class":456},[424,1489,1490],{"class":383,"line":602},[424,1491,470],{"emptyLinePlaceholder":469},[424,1493,1494,1497,1501],{"class":383,"line":635},[424,1495,1496],{"class":452},"def",[424,1498,1500],{"class":1499},"s_Opv"," summarise",[424,1502,1503],{"class":456},"(frame, by):\n",[424,1505,1506,1509,1511,1514,1517,1519],{"class":383,"line":672},[424,1507,1508],{"class":456},"    out ",[424,1510,479],{"class":452},[424,1512,1513],{"class":456}," frame.groupby(by).agg(",[424,1515,1516],{"class":452},"**",[424,1518,1394],{"class":610},[424,1520,731],{"class":456},[424,1522,1523,1526,1528,1530,1532,1535,1537,1539,1541,1543,1545],{"class":383,"line":678},[424,1524,1525],{"class":456},"    out[",[424,1527,1186],{"class":433},[424,1529,687],{"class":456},[424,1531,479],{"class":452},[424,1533,1534],{"class":456}," out[",[424,1536,1196],{"class":433},[424,1538,687],{"class":456},[424,1540,1201],{"class":452},[424,1542,1534],{"class":456},[424,1544,1206],{"class":433},[424,1546,708],{"class":456},[424,1548,1549,1552],{"class":383,"line":711},[424,1550,1551],{"class":452},"    return",[424,1553,1554],{"class":456}," out\n",[424,1556,1557],{"class":383,"line":734},[424,1558,470],{"emptyLinePlaceholder":469},[424,1560,1562,1565,1567,1570,1572],{"class":383,"line":1561},14,[424,1563,1564],{"class":456},"by_region ",[424,1566,479],{"class":452},[424,1568,1569],{"class":456}," summarise(df, ",[424,1571,778],{"class":433},[424,1573,731],{"class":456},[424,1575,1577,1580,1582,1585,1587,1589,1592,1595,1597],{"class":383,"line":1576},15,[424,1578,1579],{"class":456},"total ",[424,1581,479],{"class":452},[424,1583,1584],{"class":456}," summarise(df.assign(",[424,1586,109],{"class":722},[424,1588,479],{"class":452},[424,1590,1591],{"class":433},"\"Total\"",[424,1593,1594],{"class":456},"), ",[424,1596,778],{"class":433},[424,1598,731],{"class":456},[424,1600,1602,1605,1607],{"class":383,"line":1601},16,[424,1603,1604],{"class":456},"report ",[424,1606,479],{"class":452},[424,1608,1609],{"class":456}," pd.concat([by_region, total])\n",[424,1611,1613,1615,1618,1620,1622,1625,1627,1629,1631,1633],{"class":383,"line":1612},17,[424,1614,848],{"class":610},[424,1616,1617],{"class":456},"(report[[",[424,1619,1196],{"class":433},[424,1621,497],{"class":456},[424,1623,1624],{"class":433},"\"customers\"",[424,1626,497],{"class":456},[424,1628,1186],{"class":433},[424,1630,1225],{"class":456},[424,1632,131],{"class":610},[424,1634,1230],{"class":456},[10,1636,1637,1638,1641,1642,1644,1645,1648],{},"North has 2 customers and South 3, yet the total row says 4, not 5: customer A bought in both regions and is counted once overall. Keeping the rules in one dictionary and the derived ratio in one function guarantees that the groups and the total are computed identically. ",[14,1639,1640],{},"pivot_table(margins=True)"," does the same thing for you with an ",[14,1643,16],{}," dictionary — its ",[14,1646,1647],{},"All"," row is aggregated from the raw rows — but named aggregation gives you the ratio columns and readable names as well.",[25,1650,34,1655,34,1658,34,1661,34,1664,34,1671,34,1682,34,1686,34,1690,34,1695,34,1703,34,1707,34,1712,34,1716,34,1721,34,1725,34,1732,34,1736,34,1742,34,1747,34,1751,34,1755,34,1760,34,1763,34,1768,34,1771,34,1776,34,1779],{"viewBox":1651,"role":28,"ariaLabelledBy":1652,"xmlns":32,"style":33},"4 0 752 233",[1653,1654],"ag-total-t","ag-total-d",[36,1656,1657],{"id":1653},"Adding up the summary versus re-aggregating the raw rows",[40,1659,1660],{"id":1654},"Summing the summary rows double counts a customer who buys in two regions, adds averages together and cannot add dates. Aggregating the raw rows again with the same rules gives a correct distinct count, a true weighted price and the real first and last dates.",[44,1662],{"x":46,"y":47,"width":48,"height":1663,"fill":50},"233",[44,1665],{"x":53,"y":1054,"width":1666,"height":1667,"rx":1668,"fill":1669,"stroke":1670,"style":389},"351.0","201.0","14","#fdefd8","var(--gold,#b4740a)",[1672,1673,1675],"g",{"transform":1674},"translate(182.5,29.0) scale(1.083)",[1676,1677],"path",{"d":1678,"fill":1679,"stroke":1680,"style":1681},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4","none","var(--gold-ink,#7a4e06)","stroke-width:1.66px;stroke-linecap:round;stroke-linejoin:round",[65,1683,1383],{"x":1684,"y":1080,"style":1685},"195.5","font-size:14px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle",[383,1687],{"x1":101,"y1":1688,"x2":1689,"y2":1688,"stroke":1670,"style":59},"91.0","355.0",[65,1691,1694],{"x":1692,"y":130,"style":1693},"60.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start","distinct counts added up",[1672,1696,1698],{"transform":1697},"translate(38.5,99.5) scale(0.625)",[1676,1699],{"d":1700,"fill":1679,"stroke":1701,"style":1702},"M6 6l12 12 M18 6L6 18","var(--accent,#f43f8f)","stroke-width:2.88px;stroke-linecap:round;stroke-linejoin:round",[65,1704,1706],{"x":1692,"y":1705,"style":1693},"137.0","averages added together",[1672,1708,1710],{"transform":1709},"translate(38.5,125.5) scale(0.625)",[1676,1711],{"d":1700,"fill":1679,"stroke":1701,"style":1702},[65,1713,1715],{"x":1692,"y":1714,"style":1693},"163.0","dates cannot be summed",[1672,1717,1719],{"transform":1718},"translate(38.5,151.5) scale(0.625)",[1676,1720],{"d":1700,"fill":1679,"stroke":1701,"style":1702},[65,1722,1724],{"x":1692,"y":1723,"style":1693},"189.0","fine for plain sums only",[1672,1726,1728],{"transform":1727},"translate(38.5,177.5) scale(0.625)",[1676,1729],{"d":1730,"fill":1679,"stroke":1731,"style":1702},"M5 12.5l4.5 4.5L19 7","var(--teal,#0f9488)",[44,1733],{"x":1734,"y":1054,"width":1666,"height":1667,"rx":1668,"fill":1735,"stroke":1731,"style":389},"389.0","#d9f4f1",[1672,1737,1739],{"transform":1738},"translate(551.5,29.0) scale(1.083)",[1676,1740],{"d":1730,"fill":1679,"stroke":1741,"style":1681},"var(--teal-ink,#0b6157)",[65,1743,1746],{"x":1744,"y":1080,"style":1745},"564.5","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Same rules on all rows",[383,1748],{"x1":1749,"y1":1688,"x2":1750,"y2":1688,"stroke":1731,"style":59},"405.0","724.0",[65,1752,1754],{"x":1753,"y":130,"style":1693},"429.0","customers counted once",[1672,1756,1758],{"transform":1757},"translate(407.5,99.5) scale(0.625)",[1676,1759],{"d":1730,"fill":1679,"stroke":1731,"style":1702},[65,1761,1762],{"x":1753,"y":1705,"style":1693},"weighted price from totals",[1672,1764,1766],{"transform":1765},"translate(407.5,125.5) scale(0.625)",[1676,1767],{"d":1730,"fill":1679,"stroke":1731,"style":1702},[65,1769,1770],{"x":1753,"y":1714,"style":1693},"real first and last dates",[1672,1772,1774],{"transform":1773},"translate(407.5,151.5) scale(0.625)",[1676,1775],{"d":1730,"fill":1679,"stroke":1731,"style":1702},[65,1777,1778],{"x":1753,"y":1723,"style":1693},"one definition, two uses",[1672,1780,1782],{"transform":1781},"translate(407.5,177.5) scale(0.625)",[1676,1783],{"d":1730,"fill":1679,"stroke":1731,"style":1702},[410,1785,1787],{"id":1786},"step-6-different-aggregations-with-columns-across","Step 6 — Different aggregations with columns across",[10,1789,1790,1791,1793],{},"When the report needs months across the top as well, go back to ",[14,1792,755],{},", then flatten the two-level column labels into single names before writing:",[415,1795,1797],{"className":443,"code":1796,"language":445,"meta":420,"style":420},"df[\"Month\"] = df[\"Date\"].dt.strftime(\"%Y-%m\")\nwide = df.pivot_table(index=\"Region\", columns=\"Month\", values=[\"Revenue\", \"Customer\"],\n                      aggfunc={\"Revenue\": \"sum\", \"Customer\": \"nunique\"}, fill_value=0)\nwide.columns = [f\"{measure} {month}\" for measure, month in wide.columns]\nprint(wide.columns.tolist()[:3])   # ['Customer 2026-01', 'Customer 2026-02', 'Customer 2026-03']\n",[14,1798,1799,1824,1864,1899,1946],{"__ignoreMap":420},[424,1800,1801,1804,1807,1809,1811,1814,1816,1819,1822],{"class":383,"line":426},[424,1802,1803],{"class":456},"df[",[424,1805,1806],{"class":433},"\"Month\"",[424,1808,687],{"class":456},[424,1810,479],{"class":452},[424,1812,1813],{"class":456}," df[",[424,1815,969],{"class":433},[424,1817,1818],{"class":456},"].dt.strftime(",[424,1820,1821],{"class":433},"\"%Y-%m\"",[424,1823,731],{"class":456},[424,1825,1826,1829,1831,1833,1835,1837,1839,1841,1844,1846,1848,1850,1852,1854,1856,1858,1860,1862],{"class":383,"line":466},[424,1827,1828],{"class":456},"wide ",[424,1830,479],{"class":452},[424,1832,771],{"class":456},[424,1834,723],{"class":722},[424,1836,479],{"class":452},[424,1838,778],{"class":433},[424,1840,497],{"class":456},[424,1842,1843],{"class":722},"columns",[424,1845,479],{"class":452},[424,1847,1806],{"class":433},[424,1849,497],{"class":456},[424,1851,783],{"class":722},[424,1853,479],{"class":452},[424,1855,788],{"class":456},[424,1857,684],{"class":433},[424,1859,497],{"class":456},[424,1861,950],{"class":433},[424,1863,519],{"class":456},[424,1865,1866,1869,1871,1873,1875,1877,1879,1881,1883,1885,1887,1890,1893,1895,1897],{"class":383,"line":473},[424,1867,1868],{"class":722},"                      aggfunc",[424,1870,479],{"class":452},[424,1872,810],{"class":456},[424,1874,684],{"class":433},[424,1876,815],{"class":456},[424,1878,818],{"class":433},[424,1880,497],{"class":456},[424,1882,950],{"class":433},[424,1884,815],{"class":456},[424,1886,955],{"class":433},[424,1888,1889],{"class":456},"}, ",[424,1891,1892],{"class":722},"fill_value",[424,1894,479],{"class":452},[424,1896,47],{"class":610},[424,1898,731],{"class":456},[424,1900,1901,1904,1906,1909,1912,1915,1918,1921,1924,1927,1930,1932,1934,1937,1940,1943],{"class":383,"line":485},[424,1902,1903],{"class":456},"wide.columns ",[424,1905,479],{"class":452},[424,1907,1908],{"class":456}," [",[424,1910,1911],{"class":452},"f",[424,1913,1914],{"class":433},"\"",[424,1916,810],{"class":1917},"sSjpA",[424,1919,1920],{"class":456},"measure",[424,1922,1923],{"class":1917},"}",[424,1925,1926],{"class":1917}," {",[424,1928,1929],{"class":456},"month",[424,1931,1923],{"class":1917},[424,1933,1914],{"class":433},[424,1935,1936],{"class":452}," for",[424,1938,1939],{"class":456}," measure, month ",[424,1941,1942],{"class":452},"in",[424,1944,1945],{"class":456}," wide.columns]\n",[424,1947,1948,1950,1953,1955,1958],{"class":383,"line":522},[424,1949,848],{"class":610},[424,1951,1952],{"class":456},"(wide.columns.tolist()[:",[424,1954,158],{"class":610},[424,1956,1957],{"class":456},"])   ",[424,1959,1960],{"class":863},"# ['Customer 2026-01', 'Customer 2026-02', 'Customer 2026-03']\n",[10,1962,1963,1966],{},[14,1964,1965],{},"fill_value=0"," is safe here because both measures are counts or sums: a region with no orders in a month really did have zero revenue and zero customers. Leave it out when one of the measures is an average or a date, where zero would be a wrong answer rather than an empty one; fill those gaps per column after flattening instead. Name the flattened columns so that readers can tell the measures apart; \"Customer 2026-01\" is better renamed to \"Customers 2026-01\" with a mapping when the report is written.",[410,1968,1970],{"id":1969},"step-7-write-it-with-a-format-per-column","Step 7 — Write it with a format per column",[10,1972,1973],{},"Each measure needs its own number format in Excel — currency, whole numbers, dates:",[415,1975,1977],{"className":443,"code":1976,"language":445,"meta":420,"style":420},"from openpyxl import load_workbook\n\nreport.to_excel(\"summary.xlsx\", index_label=\"Region\")\nwb = load_workbook(\"summary.xlsx\")\nws = wb.active\nformats = {\"revenue\": \"#,##0.00\", \"units\": \"#,##0\", \"customers\": \"0\",\n           \"first_order\": \"yyyy-mm-dd\", \"last_order\": \"yyyy-mm-dd\", \"wavg_price\": \"0.000\"}\nheader = [c.value for c in ws[1]]\nfor name, fmt in formats.items():\n    col = header.index(name) + 1\n    for (cell,) in ws.iter_rows(min_row=2, min_col=col, max_col=col):\n        cell.number_format = fmt\nwb.save(\"summary.xlsx\")\n",[14,1978,1979,1992,1996,2015,2029,2039,2075,2106,2132,2144,2160,2198,2208],{"__ignoreMap":420},[424,1980,1981,1984,1987,1989],{"class":383,"line":426},[424,1982,1983],{"class":452},"from",[424,1985,1986],{"class":456}," openpyxl ",[424,1988,453],{"class":452},[424,1990,1991],{"class":456}," load_workbook\n",[424,1993,1994],{"class":383,"line":466},[424,1995,470],{"emptyLinePlaceholder":469},[424,1997,1998,2001,2004,2006,2009,2011,2013],{"class":383,"line":473},[424,1999,2000],{"class":456},"report.to_excel(",[424,2002,2003],{"class":433},"\"summary.xlsx\"",[424,2005,497],{"class":456},[424,2007,2008],{"class":722},"index_label",[424,2010,479],{"class":452},[424,2012,778],{"class":433},[424,2014,731],{"class":456},[424,2016,2017,2020,2022,2025,2027],{"class":383,"line":485},[424,2018,2019],{"class":456},"wb ",[424,2021,479],{"class":452},[424,2023,2024],{"class":456}," load_workbook(",[424,2026,2003],{"class":433},[424,2028,731],{"class":456},[424,2030,2031,2034,2036],{"class":383,"line":522},[424,2032,2033],{"class":456},"ws ",[424,2035,479],{"class":452},[424,2037,2038],{"class":456}," wb.active\n",[424,2040,2041,2044,2046,2048,2050,2052,2055,2057,2059,2061,2064,2066,2068,2070,2073],{"class":383,"line":558},[424,2042,2043],{"class":456},"formats ",[424,2045,479],{"class":452},[424,2047,1926],{"class":456},[424,2049,1196],{"class":433},[424,2051,815],{"class":456},[424,2053,2054],{"class":433},"\"#,##0.00\"",[424,2056,497],{"class":456},[424,2058,1206],{"class":433},[424,2060,815],{"class":456},[424,2062,2063],{"class":433},"\"#,##0\"",[424,2065,497],{"class":456},[424,2067,1624],{"class":433},[424,2069,815],{"class":456},[424,2071,2072],{"class":433},"\"0\"",[424,2074,580],{"class":456},[424,2076,2077,2080,2082,2085,2087,2090,2092,2094,2096,2098,2100,2103],{"class":383,"line":583},[424,2078,2079],{"class":433},"           \"first_order\"",[424,2081,815],{"class":456},[424,2083,2084],{"class":433},"\"yyyy-mm-dd\"",[424,2086,497],{"class":456},[424,2088,2089],{"class":433},"\"last_order\"",[424,2091,815],{"class":456},[424,2093,2084],{"class":433},[424,2095,497],{"class":456},[424,2097,1186],{"class":433},[424,2099,815],{"class":456},[424,2101,2102],{"class":433},"\"0.000\"",[424,2104,2105],{"class":456},"}\n",[424,2107,2108,2111,2113,2116,2119,2122,2124,2127,2129],{"class":383,"line":602},[424,2109,2110],{"class":456},"header ",[424,2112,479],{"class":452},[424,2114,2115],{"class":456}," [c.value ",[424,2117,2118],{"class":452},"for",[424,2120,2121],{"class":456}," c ",[424,2123,1942],{"class":452},[424,2125,2126],{"class":456}," ws[",[424,2128,103],{"class":610},[424,2130,2131],{"class":456},"]]\n",[424,2133,2134,2136,2139,2141],{"class":383,"line":635},[424,2135,2118],{"class":452},[424,2137,2138],{"class":456}," name, fmt ",[424,2140,1942],{"class":452},[424,2142,2143],{"class":456}," formats.items():\n",[424,2145,2146,2149,2151,2154,2157],{"class":383,"line":672},[424,2147,2148],{"class":456},"    col ",[424,2150,479],{"class":452},[424,2152,2153],{"class":456}," header.index(name) ",[424,2155,2156],{"class":452},"+",[424,2158,2159],{"class":610}," 1\n",[424,2161,2162,2165,2168,2170,2173,2176,2178,2180,2182,2185,2187,2190,2193,2195],{"class":383,"line":678},[424,2163,2164],{"class":452},"    for",[424,2166,2167],{"class":456}," (cell,) ",[424,2169,1942],{"class":452},[424,2171,2172],{"class":456}," ws.iter_rows(",[424,2174,2175],{"class":722},"min_row",[424,2177,479],{"class":452},[424,2179,131],{"class":610},[424,2181,497],{"class":456},[424,2183,2184],{"class":722},"min_col",[424,2186,479],{"class":452},[424,2188,2189],{"class":456},"col, ",[424,2191,2192],{"class":722},"max_col",[424,2194,479],{"class":452},[424,2196,2197],{"class":456},"col):\n",[424,2199,2200,2203,2205],{"class":383,"line":711},[424,2201,2202],{"class":456},"        cell.number_format ",[424,2204,479],{"class":452},[424,2206,2207],{"class":456}," fmt\n",[424,2209,2210,2213,2215],{"class":383,"line":734},[424,2211,2212],{"class":456},"wb.save(",[424,2214,2003],{"class":433},[424,2216,731],{"class":456},[10,2218,2219,2220,2222],{},"Looking up each column by its header name, rather than by letter, keeps the formatting correct when a new measure is added to ",[14,2221,1394],{},". Formats change only how numbers are displayed; the stored values keep full precision, so anyone who reuses the sheet in formulas still gets the exact weighted price rather than the three decimals on screen.",[410,2224,2226],{"id":2225},"common-pitfalls","Common pitfalls",[2228,2229,2230,2246,2252,2266],"ul",{},[2231,2232,2233,2237,2238,2241,2242,2245],"li",{},[2234,2235,2236],"strong",{},"count versus size."," ",[14,2239,2240],{},"\"count\""," counts non-missing values in a column; ",[14,2243,2244],{},"\"size\""," counts rows. They differ whenever the column has gaps.",[2231,2247,2248,2251],{},[2234,2249,2250],{},"nunique across groups."," Distinct counts do not add up; a customer in two regions is one customer overall, as the total row in Step 5 shows.",[2231,2253,2254,2237,2257,2260,2261,1032,2263,2265],{},[2234,2255,2256],{},"\"first\" and \"last\" depend on row order.",[14,2258,2259],{},"(\"Date\", \"first\")"," returns whichever row happens to come first, which changes when the sheet is sorted differently. Use ",[14,2262,1031],{},[14,2264,1035],{}," for dates, or sort explicitly before aggregating when you need the first order's other details.",[2231,2267,2268,2271],{},[2234,2269,2270],{},"Mean of a mean."," Averages of subgroup averages ignore group sizes. Recompute from raw rows.",[410,2273,2275],{"id":2274},"conclusion","Conclusion",[10,2277,2278,2279,2281,2282,1032,2284,2286,2287,2289,2290,2292],{},"Give each summary column the function that answers its question: sums for totals, ",[14,2280,1027],{}," for distinct counts, ",[14,2283,1031],{},[14,2285,1035],{}," for first and last dates, and ratios of sums for weighted averages. Use named aggregation for readable single-level results, ",[14,2288,755],{}," with an ",[14,2291,16],{}," dictionary when you also need columns across, and compute totals by applying the same rules to all rows rather than adding up the summary.",[410,2294,2296],{"id":2295},"frequently-asked-questions","Frequently asked questions",[10,2298,2299,2302],{},[2234,2300,2301],{},"How do I use a different aggregation for each column in pivot_table?","\nPass aggfunc a dictionary that maps each value column to a function name, such as {\"Revenue\":\"sum\",\"Price\":\"mean\"}. A list as the dictionary value applies several functions to that column and produces two-level column labels.",[10,2304,2305,2308],{},[2234,2306,2307],{},"What is named aggregation?","\nA groupby().agg() form where each keyword argument is an output column name and its value is a tuple of source column and function, such as revenue=(\"Revenue\",\"sum\"). It produces flat, readable column names in one step.",[10,2310,2311,2314],{},[2234,2312,2313],{},"How do I calculate a weighted average price per group?","\nAggregate the parts separately — the sum of revenue and the sum of units — and divide afterwards. Averaging the price column gives each order equal weight regardless of its size.",[10,2316,2317,2320],{},[2234,2318,2319],{},"How do I add a total row with the same aggregations?","\nRun the same aggregation on the whole frame, for example by grouping on a constant column, and append it to the grouped result. That keeps distinct counts and averages correct in the total row.",[410,2322,2324],{"id":2323},"related","Related",[2228,2326,2327,2333,2340,2347],{},[2231,2328,2329,2330,2332],{},"Up one level: ",[19,2331,22],{"href":21}," — pivots from Excel sheets.",[2231,2334,2335,2339],{},[19,2336,2338],{"href":2337},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fbuild-a-crosstab-from-excel-data-with-pandas\u002F","Build a Crosstab from Excel Data with pandas"," — counts and shares of category combinations.",[2231,2341,2342,2346],{},[19,2343,2345],{"href":2344},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fadd-subtotals-and-grand-totals-to-a-pandas-pivot-table\u002F","Add Subtotals and Grand Totals to a pandas Pivot Table"," — totals for each group.",[2231,2348,2349,2353],{},[19,2350,2352],{"href":2351},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fsumif-and-sumifs-equivalent-in-pandas\u002F","SUMIF and SUMIFS Equivalent in pandas"," — conditional sums outside a pivot.",[2355,2356,2357],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}",{"title":420,"searchDepth":466,"depth":466,"links":2359},[2360,2361,2362,2363,2364,2365,2366,2367,2368,2369,2370,2371],{"id":412,"depth":466,"text":413},{"id":749,"depth":466,"text":750},{"id":874,"depth":466,"text":875},{"id":1166,"depth":466,"text":1167},{"id":1251,"depth":466,"text":1252},{"id":1376,"depth":466,"text":1377},{"id":1786,"depth":466,"text":1787},{"id":1969,"depth":466,"text":1970},{"id":2225,"depth":466,"text":2226},{"id":2274,"depth":466,"text":2275},{"id":2295,"depth":466,"text":2296},{"id":2323,"depth":466,"text":2324},"2026-09-23","Sum revenue, average price, count distinct customers and find the last order date in one summary table. Use pivot_table's aggfunc dictionary or groupby named aggregation, compute weighted averages correctly, add a total row that uses the same rules, and write readable column names to Excel.","md",[2376,2378,2380,2382],{"q":2301,"a":2377},"Pass aggfunc a dictionary that maps each value column to a function name, such as {\"Revenue\":\"sum\",\"Price\":\"mean\"}. A list as the dictionary value applies several functions to that column and produces two-level column labels.",{"q":2307,"a":2379},"A groupby().agg() form where each keyword argument is an output column name and its value is a tuple of source column and function, such as revenue=(\"Revenue\",\"sum\"). It produces flat, readable column names in one step.",{"q":2313,"a":2381},"Aggregate the parts separately — the sum of revenue and the sum of units — and divide afterwards. Averaging the price column gives each order equal weight regardless of its size.",{"q":2319,"a":2383},"Run the same aggregation on the whole frame, for example by grouping on a constant column, and append it to the grouped result. That keeps distinct counts and averages correct in the total row.","use different aggregations per column in a pandas pivot",null,{"breadcrumb":2387},[2388,2390,2393],{"name":2389,"item":1201},"Home",{"name":2391,"item":2392},"Advanced Data Transformation and Cleaning for Excel Automation","\u002Fadvanced-data-transformation-and-cleaning\u002F",{"name":2394,"item":21},"Creating Pivot Tables from Excel Data with Pandas","\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fuse-different-aggregations-per-column-in-a-pivot",{"title":2397,"description":2398},"Different Aggregations per Column in a pandas Pivot (aggfunc dict)","Apply sum, mean, nunique, min and max to different columns in one pandas summary — pivot_table aggfunc dicts, groupby named aggregation, weighted averages, custom functions, a consistent total row and Excel export.","use-different-aggregations-per-column-in-a-pivot","advanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fuse-different-aggregations-per-column-in-a-pivot\u002Findex",[2402,2403],"pivots-and-summaries","pandas","how-to","Axcmc0v3AXAs0Gvq98AtgOtY679U2m-PiUlw-bKiBVQ",[2407,2411],{"title":2408,"path":2409,"stem":2410,"children":-1},"Unpivot a Wide Excel Sheet with pandas melt","\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Funpivot-a-wide-excel-sheet-with-pandas-melt","advanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Funpivot-a-wide-excel-sheet-with-pandas-melt\u002Findex",{"title":2412,"path":2413,"stem":2414,"children":-1},"Excel Formula Equivalents in pandas","\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas","advanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Findex",[2416,2418],{"path":2417,"title":2394},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data",{"path":2419,"title":2391},"\u002Fadvanced-data-transformation-and-cleaning",[],[2422,2425,2428,2431,2433,2436],{"path":2423,"title":2424,"kind":2404},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-customer-churn-report-from-subscription-data","Build a Customer Churn Report from Subscription Data",{"path":2426,"title":2427,"kind":2404},"\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Frefresh-pivot-tables-and-queries-in-excel-with-python","Refresh Excel Pivot Tables and Queries with Python",{"path":2429,"title":2430,"kind":2404},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fadd-a-native-excel-pivot-table-with-python","Add a Native Excel Pivot Table with Python",{"path":2432,"title":2345,"kind":2404},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fadd-subtotals-and-grand-totals-to-a-pandas-pivot-table",{"path":2434,"title":2435,"kind":2404},"\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":2437,"title":2438,"kind":2404},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fbuild-a-cohort-retention-table-from-excel-data","Build a Cohort Retention Table from Excel Data",1790972086729]