[{"data":1,"prerenderedAt":2425},["ShallowReactive",2],{"doc:\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Frun-a-pareto-analysis-on-excel-data-with-pandas":3,"surround:\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Frun-a-pareto-analysis-on-excel-data-with-pandas":2391,"ancestors:\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Frun-a-pareto-analysis-on-excel-data-with-pandas":2400,"children:\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Frun-a-pareto-analysis-on-excel-data-with-pandas":2405,"related:\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Frun-a-pareto-analysis-on-excel-data-with-pandas":2406},{"id":4,"title":5,"body":6,"dateModified":2357,"datePublished":2357,"description":2358,"extension":2359,"faq":2360,"keyword":2369,"kind":2370,"meta":2371,"navigation":278,"path":2379,"seo":2380,"slug":2383,"stem":2384,"topics":2385,"type":2389,"__hash__":2390},"docs\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Frun-a-pareto-analysis-on-excel-data-with-pandas\u002Findex.md","Run a Pareto Analysis on Excel Data with pandas",{"type":7,"value":8,"toc":2342},"minimark",[9,19,199,204,232,238,242,250,401,408,412,415,557,567,571,585,753,763,958,962,965,1174,1186,1190,1193,1716,1724,1834,1838,1841,1977,1980,1984,1991,2199,2215,2219,2250,2254,2261,2265,2277,2281,2287,2293,2299,2305,2309,2338],[10,11,12,13,18],"p",{},"The 80\u002F20 rule is less a law than a question: which few customers, products or causes account for most of the total? A Pareto analysis answers it with a sorted table and a running share — and the answer tells a business where to spend its attention. The mechanics are short in pandas, but two details are regularly got wrong: rows must be aggregated before ranking, and the item that pushes the running total past 80% has to be counted inside the 80%, not just outside it. This page, part of ",[14,15,17],"a",{"href":16},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002F","Creating Pivot Tables from Excel Data with Pandas",", builds the table, an ABC classification and a native Excel Pareto chart.",[20,21,29,30,29,34,29,38,29,46,29,54,29,60,29,64,29,68,29,71,29,75,29,78,29,82,29,86,29,92,29,96,29,100,29,104,29,108,29,112,29,116,29,120,29,124,29,128,29,137,29,142,29,147,29,152,29,157,29,162,29,167,29,172,29,177,29,182,29,187,29,194],"svg",{"viewBox":22,"role":23,"ariaLabelledBy":24,"xmlns":27,"style":28},"4 0 748 232","img",[25,26],"par-chart-t","par-chart-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:748px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[31,32,33],"title",{"id":25},"Customer revenue sorted, with the cumulative share",[35,36,37],"desc",{"id":26},"A Pareto view of ten customers. Columns show revenue in thousands from Northwind at 42 down to Margie at 0.2. The cumulative share line rises steeply: 42% after one customer, 73% after two, 85% after three, then flattens towards 100%. Three customers make up more than 80% of revenue.",[39,40],"rect",{"x":41,"y":42,"width":43,"height":44,"fill":45},"4","0","748","232","#ffffff",[47,48],"line",{"x1":49,"y1":50,"x2":51,"y2":50,"stroke":52,"style":53},"46.7","194.0","736.0","var(--line,#cdd5e6)","stroke-width:1px",[55,56,42],"text",{"x":57,"y":58,"style":59},"27.4","198.0","font-size:11px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle",[47,61],{"x1":49,"y1":62,"x2":51,"y2":62,"stroke":52,"style":63},"137.3","stroke-width:1px;stroke-dasharray:5 4",[55,65,67],{"x":57,"y":66,"style":59},"141.3","20",[47,69],{"x1":49,"y1":70,"x2":51,"y2":70,"stroke":52,"style":63},"80.7",[55,72,74],{"x":57,"y":73,"style":59},"84.7","40",[47,76],{"x1":49,"y1":77,"x2":51,"y2":77,"stroke":52,"style":63},"24.0",[55,79,81],{"x":57,"y":80,"style":59},"28.0","60",[47,83],{"x1":49,"y1":50,"x2":51,"y2":50,"stroke":84,"style":85},"var(--muted,#5b6780)","stroke-width:1.5px",[55,87,91],{"x":88,"y":89,"style":90},"81.2","212.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","Northwind",[55,93,95],{"x":94,"y":89,"style":90},"150.1","Contoso",[55,97,99],{"x":98,"y":89,"style":90},"219.1","Fabrikam",[55,101,103],{"x":102,"y":89,"style":90},"288.0","Litware",[55,105,107],{"x":106,"y":89,"style":90},"356.9","Adatum",[55,109,111],{"x":110,"y":89,"style":90},"425.8","Proseware",[55,113,115],{"x":114,"y":89,"style":90},"494.8","Tailspin",[55,117,119],{"x":118,"y":89,"style":90},"563.7","Wingtip",[55,121,123],{"x":122,"y":89,"style":90},"632.6","Lucerne",[55,125,127],{"x":126,"y":89,"style":90},"701.5","Margie",[39,129],{"x":130,"y":131,"width":132,"height":133,"rx":134,"fill":135,"stroke":136,"style":85},"63.2","75.0","36.0","119.0","3","#f0f4ff","var(--brand,#5b5cf0)",[39,138],{"x":139,"y":140,"width":132,"height":141,"rx":134,"fill":135,"stroke":136,"style":85},"132.1","106.2","87.8",[39,143],{"x":144,"y":145,"width":132,"height":146,"rx":134,"fill":135,"stroke":136,"style":85},"201.1","160.0","34.0",[39,148],{"x":149,"y":150,"width":132,"height":151,"rx":134,"fill":135,"stroke":136,"style":85},"270.0","175.6","18.4",[39,153],{"x":154,"y":155,"width":132,"height":156,"rx":134,"fill":135,"stroke":136,"style":85},"338.9","184.1","9.9",[39,158],{"x":159,"y":160,"width":132,"height":161,"rx":134,"fill":135,"stroke":136,"style":85},"407.8","187.8","6.2",[39,163],{"x":164,"y":165,"width":132,"height":166,"rx":134,"fill":135,"stroke":136,"style":85},"476.8","190.0","4.0",[39,168],{"x":169,"y":170,"width":132,"height":171,"rx":134,"fill":135,"stroke":136,"style":85},"545.7","191.7","2.3",[39,173],{"x":174,"y":175,"width":132,"height":176,"rx":134,"fill":135,"stroke":136,"style":85},"614.6","192.9","1.1",[39,178],{"x":179,"y":180,"width":132,"height":181,"rx":134,"fill":135,"stroke":136,"style":85},"683.5","193.4","0.6",[47,183],{"x1":98,"y1":184,"x2":98,"y2":50,"stroke":185,"style":186},"20.0","var(--accent,#f43f8f)","stroke-width:1.5px;stroke-dasharray:5 4",[39,188],{"x":189,"y":190,"width":191,"height":184,"rx":192,"fill":193,"stroke":185,"style":53},"173.0","8.0","92.2","10","#fee8f2",[55,195,198],{"x":98,"y":196,"style":197},"22.0","font-size:11px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","80% reached",[200,201,203],"h2",{"id":202},"prerequisites","Prerequisites",[205,206,211],"pre",{"className":207,"code":208,"language":209,"meta":210,"style":210},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas openpyxl\n","bash","",[212,213,214],"code",{"__ignoreMap":210},[215,216,218,222,226,229],"span",{"class":47,"line":217},1,[215,219,221],{"class":220},"sMTad","pip",[215,223,225],{"class":224},"srMev"," install",[215,227,228],{"class":224}," pandas",[215,230,231],{"class":224}," openpyxl\n",[10,233,234,237],{},[212,235,236],{},"orders.xlsx"," has twenty orders for ten customers — each customer appears twice — adding up to 100,000 in revenue.",[200,239,241],{"id":240},"step-1-aggregate-before-you-rank","Step 1 — Aggregate before you rank",[10,243,244,245,249],{},"A Pareto analysis ranks ",[246,247,248],"em",{},"items",", so every row for the same customer has to be combined first. Ranking the raw orders would split a big customer across several lines and understate its share:",[205,251,255],{"className":252,"code":253,"language":254,"meta":210,"style":210},"language-python shiki shiki-themes github-light github-dark-high-contrast","import pandas as pd\n\norders = pd.read_excel(\"orders.xlsx\")\nby_customer = (orders.groupby(\"customer\", as_index=False)[\"amount\"].sum()\n                     .sort_values(\"amount\", ascending=False, ignore_index=True))\nprint(by_customer.to_string(index=False))\nprint(\"total:\", by_customer[\"amount\"].sum())\n","python",[212,256,257,273,280,298,334,364,382],{"__ignoreMap":210},[215,258,259,263,267,270],{"class":47,"line":217},[215,260,262],{"class":261},"s-kum","import",[215,264,266],{"class":265},"skGVy"," pandas ",[215,268,269],{"class":261},"as",[215,271,272],{"class":265}," pd\n",[215,274,276],{"class":47,"line":275},2,[215,277,279],{"emptyLinePlaceholder":278},true,"\n",[215,281,283,286,289,292,295],{"class":47,"line":282},3,[215,284,285],{"class":265},"orders ",[215,287,288],{"class":261},"=",[215,290,291],{"class":265}," pd.read_excel(",[215,293,294],{"class":224},"\"orders.xlsx\"",[215,296,297],{"class":265},")\n",[215,299,301,304,306,309,312,315,319,321,325,328,331],{"class":47,"line":300},4,[215,302,303],{"class":265},"by_customer ",[215,305,288],{"class":261},[215,307,308],{"class":265}," (orders.groupby(",[215,310,311],{"class":224},"\"customer\"",[215,313,314],{"class":265},", ",[215,316,318],{"class":317},"sa561","as_index",[215,320,288],{"class":261},[215,322,324],{"class":323},"sP0c6","False",[215,326,327],{"class":265},")[",[215,329,330],{"class":224},"\"amount\"",[215,332,333],{"class":265},"].sum()\n",[215,335,337,340,342,344,347,349,351,353,356,358,361],{"class":47,"line":336},5,[215,338,339],{"class":265},"                     .sort_values(",[215,341,330],{"class":224},[215,343,314],{"class":265},[215,345,346],{"class":317},"ascending",[215,348,288],{"class":261},[215,350,324],{"class":323},[215,352,314],{"class":265},[215,354,355],{"class":317},"ignore_index",[215,357,288],{"class":261},[215,359,360],{"class":323},"True",[215,362,363],{"class":265},"))\n",[215,365,367,370,373,376,378,380],{"class":47,"line":366},6,[215,368,369],{"class":323},"print",[215,371,372],{"class":265},"(by_customer.to_string(",[215,374,375],{"class":317},"index",[215,377,288],{"class":261},[215,379,324],{"class":323},[215,381,363],{"class":265},[215,383,385,387,390,393,396,398],{"class":47,"line":384},7,[215,386,369],{"class":323},[215,388,389],{"class":265},"(",[215,391,392],{"class":224},"\"total:\"",[215,394,395],{"class":265},", by_customer[",[215,397,330],{"class":224},[215,399,400],{"class":265},"].sum())\n",[10,402,403,404,407],{},"Each customer now has one row, largest first. ",[212,405,406],{},"ignore_index=True"," renumbers the rows 0, 1, 2… in rank order, which is handy for counting how many items a threshold needs.",[200,409,411],{"id":410},"step-2-compute-the-cumulative-share","Step 2 — Compute the cumulative share",[10,413,414],{},"Divide each amount by the total to get its share, and take the running sum of the shares:",[205,416,418],{"className":252,"code":417,"language":254,"meta":210,"style":210},"total = by_customer[\"amount\"].sum()\nby_customer[\"share\"] = by_customer[\"amount\"] \u002F total\nby_customer[\"cum_share\"] = by_customer[\"share\"].cumsum()\nby_customer[\"rank\"] = range(1, len(by_customer) + 1)\nby_customer[\"item_share\"] = by_customer[\"rank\"] \u002F len(by_customer)\nprint(by_customer.round(3).to_string(index=False))\n",[212,419,420,434,459,477,512,537],{"__ignoreMap":210},[215,421,422,425,427,430,432],{"class":47,"line":217},[215,423,424],{"class":265},"total ",[215,426,288],{"class":261},[215,428,429],{"class":265}," by_customer[",[215,431,330],{"class":224},[215,433,333],{"class":265},[215,435,436,439,442,445,447,449,451,453,456],{"class":47,"line":275},[215,437,438],{"class":265},"by_customer[",[215,440,441],{"class":224},"\"share\"",[215,443,444],{"class":265},"] ",[215,446,288],{"class":261},[215,448,429],{"class":265},[215,450,330],{"class":224},[215,452,444],{"class":265},[215,454,455],{"class":261},"\u002F",[215,457,458],{"class":265}," total\n",[215,460,461,463,466,468,470,472,474],{"class":47,"line":282},[215,462,438],{"class":265},[215,464,465],{"class":224},"\"cum_share\"",[215,467,444],{"class":265},[215,469,288],{"class":261},[215,471,429],{"class":265},[215,473,441],{"class":224},[215,475,476],{"class":265},"].cumsum()\n",[215,478,479,481,484,486,488,491,493,496,498,501,504,507,510],{"class":47,"line":300},[215,480,438],{"class":265},[215,482,483],{"class":224},"\"rank\"",[215,485,444],{"class":265},[215,487,288],{"class":261},[215,489,490],{"class":323}," range",[215,492,389],{"class":265},[215,494,495],{"class":323},"1",[215,497,314],{"class":265},[215,499,500],{"class":323},"len",[215,502,503],{"class":265},"(by_customer) ",[215,505,506],{"class":261},"+",[215,508,509],{"class":323}," 1",[215,511,297],{"class":265},[215,513,514,516,519,521,523,525,527,529,531,534],{"class":47,"line":336},[215,515,438],{"class":265},[215,517,518],{"class":224},"\"item_share\"",[215,520,444],{"class":265},[215,522,288],{"class":261},[215,524,429],{"class":265},[215,526,483],{"class":224},[215,528,444],{"class":265},[215,530,455],{"class":261},[215,532,533],{"class":323}," len",[215,535,536],{"class":265},"(by_customer)\n",[215,538,539,541,544,546,549,551,553,555],{"class":47,"line":366},[215,540,369],{"class":323},[215,542,543],{"class":265},"(by_customer.round(",[215,545,134],{"class":323},[215,547,548],{"class":265},").to_string(",[215,550,375],{"class":317},[215,552,288],{"class":261},[215,554,324],{"class":323},[215,556,363],{"class":265},[10,558,559,562,563,566],{},[212,560,561],{},"cum_share"," climbs from 0.42 after Northwind to 0.73 after Contoso and 0.85 after Fabrikam, then flattens. ",[212,564,565],{},"item_share"," — the rank as a fraction of the item count — gives the other half of the 80\u002F20 statement: after three customers, 30% of the customer base, the business has 85% of its revenue. Real data rarely lands on exactly 80\u002F20, and saying \"30% of customers bring 85% of revenue\" is more useful than forcing the familiar numbers.",[200,568,570],{"id":569},"step-3-count-the-items-needed-to-reach-80","Step 3 — Count the items needed to reach 80%",[10,572,573,574,577,578,581,582,584],{},"The question \"how many customers make up 80%?\" has an off-by-one trap. Filtering on ",[212,575,576],{},"cum_share \u003C= 0.8"," returns the customers ",[246,579,580],{},"before"," the threshold is reached — Northwind and Contoso, 73% — and misses Fabrikam, whose revenue carries the total past 80%. Test the cumulative share ",[246,583,580],{}," each item instead:",[205,586,588],{"className":252,"code":587,"language":254,"meta":210,"style":210},"by_customer[\"prev_cum\"] = by_customer[\"cum_share\"] - by_customer[\"share\"]\ntop = by_customer[by_customer[\"prev_cum\"] \u003C 0.8]\nprint(len(top), \"customers reach\", round(top[\"cum_share\"].iloc[-1], 3), \"of revenue:\", top[\"customer\"].tolist())\n\nwrong = by_customer[by_customer[\"cum_share\"] \u003C= 0.8]\nprint(\"with cum_share \u003C= 0.8:\", len(wrong), \"customers,\", round(wrong[\"cum_share\"].iloc[-1], 3))\n",[212,589,590,617,639,689,693,713],{"__ignoreMap":210},[215,591,592,594,597,599,601,603,605,607,610,612,614],{"class":47,"line":217},[215,593,438],{"class":265},[215,595,596],{"class":224},"\"prev_cum\"",[215,598,444],{"class":265},[215,600,288],{"class":261},[215,602,429],{"class":265},[215,604,465],{"class":224},[215,606,444],{"class":265},[215,608,609],{"class":261},"-",[215,611,429],{"class":265},[215,613,441],{"class":224},[215,615,616],{"class":265},"]\n",[215,618,619,622,624,627,629,631,634,637],{"class":47,"line":275},[215,620,621],{"class":265},"top ",[215,623,288],{"class":261},[215,625,626],{"class":265}," by_customer[by_customer[",[215,628,596],{"class":224},[215,630,444],{"class":265},[215,632,633],{"class":261},"\u003C",[215,635,636],{"class":323}," 0.8",[215,638,616],{"class":265},[215,640,641,643,645,647,650,653,655,658,661,663,666,668,670,673,675,678,681,684,686],{"class":47,"line":282},[215,642,369],{"class":323},[215,644,389],{"class":265},[215,646,500],{"class":323},[215,648,649],{"class":265},"(top), ",[215,651,652],{"class":224},"\"customers reach\"",[215,654,314],{"class":265},[215,656,657],{"class":323},"round",[215,659,660],{"class":265},"(top[",[215,662,465],{"class":224},[215,664,665],{"class":265},"].iloc[",[215,667,609],{"class":261},[215,669,495],{"class":323},[215,671,672],{"class":265},"], ",[215,674,134],{"class":323},[215,676,677],{"class":265},"), ",[215,679,680],{"class":224},"\"of revenue:\"",[215,682,683],{"class":265},", top[",[215,685,311],{"class":224},[215,687,688],{"class":265},"].tolist())\n",[215,690,691],{"class":47,"line":300},[215,692,279],{"emptyLinePlaceholder":278},[215,694,695,698,700,702,704,706,709,711],{"class":47,"line":336},[215,696,697],{"class":265},"wrong ",[215,699,288],{"class":261},[215,701,626],{"class":265},[215,703,465],{"class":224},[215,705,444],{"class":265},[215,707,708],{"class":261},"\u003C=",[215,710,636],{"class":323},[215,712,616],{"class":265},[215,714,715,717,719,722,724,726,729,732,734,736,739,741,743,745,747,749,751],{"class":47,"line":366},[215,716,369],{"class":323},[215,718,389],{"class":265},[215,720,721],{"class":224},"\"with cum_share \u003C= 0.8:\"",[215,723,314],{"class":265},[215,725,500],{"class":323},[215,727,728],{"class":265},"(wrong), ",[215,730,731],{"class":224},"\"customers,\"",[215,733,314],{"class":265},[215,735,657],{"class":323},[215,737,738],{"class":265},"(wrong[",[215,740,465],{"class":224},[215,742,665],{"class":265},[215,744,609],{"class":261},[215,746,495],{"class":323},[215,748,672],{"class":265},[215,750,134],{"class":323},[215,752,363],{"class":265},[10,754,755,758,759,762],{},[212,756,757],{},"prev_cum \u003C 0.8"," says \"the total so far had not yet reached 80% when this item was added\", which is exactly the set of items needed to get there: three customers covering 85%. The other filter reports two customers covering 73%, which answers a different question — how many items stay ",[246,760,761],{},"under"," 80% — that nobody asked.",[20,764,29,770,29,773,29,776,29,781,29,787,29,793,29,797,29,803,29,807,29,811,29,815,29,819,29,823,29,827,29,830,29,834,29,836,29,840,29,842,29,845,29,847,29,849,29,851,29,854,29,857,29,860,29,864,29,867,29,869,29,872,29,874,29,876,29,878,29,881,29,884,29,887,29,889,29,891,29,893,29,896,29,898,29,901,29,903,29,905,29,908,29,911,29,913,29,915,29,917,29,920,29,922,29,925,29,929,29,932,29,935,29,939,29,941,29,944,29,946,29,949,29,951,29,954,29,956],{"viewBox":765,"role":23,"ariaLabelledBy":766,"xmlns":27,"style":769},"185 0 389 228",[767,768],"par-boundary-t","par-boundary-d","width:100%;max-width:389px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[31,771,772],{"id":767},"The item that crosses 80% belongs in the top group",[35,774,775],{"id":768},"A table of the first four customers with share, cumulative share and cumulative share before the item. Northwind and Contoso have cumulative shares of 42% and 73%. Fabrikam takes it from 73% to 85%, so its previous cumulative share is below 80% and it is included. Litware starts at 85% and is not.",[39,777],{"x":778,"y":42,"width":779,"height":780,"fill":45},"185","389","228",[55,782,786],{"x":783,"y":784,"style":785},"380.0","31.0","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","prev_cum \u003C 0.8 includes the crossing item",[39,788],{"x":789,"y":790,"width":791,"height":77,"rx":42,"fill":792,"stroke":52,"style":53},"201.9","48.0","32.0","#e7ebef",[39,794],{"x":795,"y":790,"width":796,"height":77,"rx":42,"fill":792,"stroke":52,"style":53},"233.9","88.8",[55,798,802],{"x":799,"y":800,"style":801},"278.3","65.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[39,804],{"x":805,"y":790,"width":806,"height":77,"rx":42,"fill":792,"stroke":52,"style":53},"322.7","58.9",[55,808,810],{"x":809,"y":800,"style":801},"352.2","B",[39,812],{"x":813,"y":790,"width":814,"height":77,"rx":42,"fill":792,"stroke":52,"style":53},"381.6","91.6",[55,816,818],{"x":817,"y":800,"style":801},"427.4","C",[39,820],{"x":821,"y":790,"width":822,"height":77,"rx":42,"fill":792,"stroke":52,"style":53},"473.2","84.9",[55,824,826],{"x":825,"y":800,"style":801},"515.7","D",[39,828],{"x":789,"y":829,"width":791,"height":80,"rx":42,"fill":792,"stroke":52,"style":53},"72.0",[55,831,495],{"x":832,"y":833,"style":801},"217.9","91.0",[39,835],{"x":795,"y":829,"width":796,"height":80,"rx":42,"fill":45,"stroke":52,"style":53},[55,837,839],{"x":799,"y":833,"style":838},"font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","customer",[39,841],{"x":805,"y":829,"width":806,"height":80,"rx":42,"fill":45,"stroke":52,"style":53},[55,843,844],{"x":809,"y":833,"style":838},"share",[39,846],{"x":813,"y":829,"width":814,"height":80,"rx":42,"fill":45,"stroke":52,"style":53},[55,848,561],{"x":817,"y":833,"style":838},[39,850],{"x":821,"y":829,"width":822,"height":80,"rx":42,"fill":45,"stroke":52,"style":53},[55,852,853],{"x":825,"y":833,"style":838},"prev_cum",[39,855],{"x":789,"y":856,"width":791,"height":80,"rx":42,"fill":792,"stroke":52,"style":53},"100.0",[55,858,859],{"x":832,"y":133,"style":801},"2",[39,861],{"x":795,"y":856,"width":796,"height":80,"rx":42,"fill":862,"stroke":863,"style":85},"#d9f4f1","var(--teal,#0f9488)",[55,865,91],{"x":799,"y":133,"style":866},"font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle",[39,868],{"x":805,"y":856,"width":806,"height":80,"rx":42,"fill":862,"stroke":863,"style":85},[55,870,871],{"x":809,"y":133,"style":866},"42%",[39,873],{"x":813,"y":856,"width":814,"height":80,"rx":42,"fill":862,"stroke":863,"style":85},[55,875,871],{"x":817,"y":133,"style":866},[39,877],{"x":821,"y":856,"width":822,"height":80,"rx":42,"fill":862,"stroke":863,"style":85},[55,879,880],{"x":825,"y":133,"style":866},"0%",[39,882],{"x":789,"y":883,"width":791,"height":80,"rx":42,"fill":792,"stroke":52,"style":53},"128.0",[55,885,134],{"x":832,"y":886,"style":801},"147.0",[39,888],{"x":795,"y":883,"width":796,"height":80,"rx":42,"fill":862,"stroke":863,"style":85},[55,890,95],{"x":799,"y":886,"style":866},[39,892],{"x":805,"y":883,"width":806,"height":80,"rx":42,"fill":862,"stroke":863,"style":85},[55,894,895],{"x":809,"y":886,"style":866},"31%",[39,897],{"x":813,"y":883,"width":814,"height":80,"rx":42,"fill":862,"stroke":863,"style":85},[55,899,900],{"x":817,"y":886,"style":866},"73%",[39,902],{"x":821,"y":883,"width":822,"height":80,"rx":42,"fill":862,"stroke":863,"style":85},[55,904,871],{"x":825,"y":886,"style":866},[39,906],{"x":789,"y":907,"width":791,"height":80,"rx":42,"fill":792,"stroke":52,"style":53},"156.0",[55,909,41],{"x":832,"y":910,"style":801},"175.0",[39,912],{"x":795,"y":907,"width":796,"height":80,"rx":42,"fill":862,"stroke":863,"style":85},[55,914,99],{"x":799,"y":910,"style":866},[39,916],{"x":805,"y":907,"width":806,"height":80,"rx":42,"fill":862,"stroke":863,"style":85},[55,918,919],{"x":809,"y":910,"style":866},"12%",[39,921],{"x":813,"y":907,"width":814,"height":80,"rx":42,"fill":862,"stroke":863,"style":85},[55,923,924],{"x":817,"y":910,"style":866},"85%",[39,926],{"x":821,"y":907,"width":822,"height":80,"rx":42,"fill":927,"stroke":928,"style":85},"#fdefd8","var(--gold,#b4740a)",[55,930,900],{"x":825,"y":910,"style":931},"font-size:12px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle",[39,933],{"x":789,"y":934,"width":791,"height":80,"rx":42,"fill":792,"stroke":52,"style":53},"184.0",[55,936,938],{"x":832,"y":937,"style":801},"203.0","5",[39,940],{"x":795,"y":934,"width":796,"height":80,"rx":42,"fill":45,"stroke":52,"style":53},[55,942,103],{"x":799,"y":937,"style":943},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle",[39,945],{"x":805,"y":934,"width":806,"height":80,"rx":42,"fill":45,"stroke":52,"style":53},[55,947,948],{"x":809,"y":937,"style":943},"6.5%",[39,950],{"x":813,"y":934,"width":814,"height":80,"rx":42,"fill":45,"stroke":52,"style":53},[55,952,953],{"x":817,"y":937,"style":943},"91.5%",[39,955],{"x":821,"y":934,"width":822,"height":80,"rx":42,"fill":45,"stroke":52,"style":53},[55,957,924],{"x":825,"y":937,"style":943},[200,959,961],{"id":960},"step-4-classify-items-into-a-b-and-c","Step 4 — Classify items into A, B and C",[10,963,964],{},"ABC classification extends the same idea to three tiers: A items bring the first 80% of the total, B the next 15%, C the last 5%. Use the same \"before this item\" rule for each boundary so every item lands in the tier where it starts:",[205,966,968],{"className":252,"code":967,"language":254,"meta":210,"style":210},"import numpy as np\n\nby_customer[\"class\"] = np.select(\n    [by_customer[\"prev_cum\"] \u003C 0.80, by_customer[\"prev_cum\"] \u003C 0.95],\n    [\"A\", \"B\"], default=\"C\")\nsummary = by_customer.groupby(\"class\").agg(customers=(\"customer\", \"count\"), revenue=(\"amount\", \"sum\"))\nsummary[\"revenue_share\"] = (summary[\"revenue\"] \u002F total).round(3)\nprint(by_customer[[\"customer\", \"amount\", \"cum_share\", \"class\"]].round(3).to_string(index=False))\nprint(summary)\n",[212,969,970,982,986,1000,1028,1053,1100,1129,1166],{"__ignoreMap":210},[215,971,972,974,977,979],{"class":47,"line":217},[215,973,262],{"class":261},[215,975,976],{"class":265}," numpy ",[215,978,269],{"class":261},[215,980,981],{"class":265}," np\n",[215,983,984],{"class":47,"line":275},[215,985,279],{"emptyLinePlaceholder":278},[215,987,988,990,993,995,997],{"class":47,"line":282},[215,989,438],{"class":265},[215,991,992],{"class":224},"\"class\"",[215,994,444],{"class":265},[215,996,288],{"class":261},[215,998,999],{"class":265}," np.select(\n",[215,1001,1002,1005,1007,1009,1011,1014,1016,1018,1020,1022,1025],{"class":47,"line":300},[215,1003,1004],{"class":265},"    [by_customer[",[215,1006,596],{"class":224},[215,1008,444],{"class":265},[215,1010,633],{"class":261},[215,1012,1013],{"class":323}," 0.80",[215,1015,395],{"class":265},[215,1017,596],{"class":224},[215,1019,444],{"class":265},[215,1021,633],{"class":261},[215,1023,1024],{"class":323}," 0.95",[215,1026,1027],{"class":265},"],\n",[215,1029,1030,1033,1036,1038,1041,1043,1046,1048,1051],{"class":47,"line":336},[215,1031,1032],{"class":265},"    [",[215,1034,1035],{"class":224},"\"A\"",[215,1037,314],{"class":265},[215,1039,1040],{"class":224},"\"B\"",[215,1042,672],{"class":265},[215,1044,1045],{"class":317},"default",[215,1047,288],{"class":261},[215,1049,1050],{"class":224},"\"C\"",[215,1052,297],{"class":265},[215,1054,1055,1058,1060,1063,1065,1068,1071,1073,1075,1077,1079,1082,1084,1087,1089,1091,1093,1095,1098],{"class":47,"line":366},[215,1056,1057],{"class":265},"summary ",[215,1059,288],{"class":261},[215,1061,1062],{"class":265}," by_customer.groupby(",[215,1064,992],{"class":224},[215,1066,1067],{"class":265},").agg(",[215,1069,1070],{"class":317},"customers",[215,1072,288],{"class":261},[215,1074,389],{"class":265},[215,1076,311],{"class":224},[215,1078,314],{"class":265},[215,1080,1081],{"class":224},"\"count\"",[215,1083,677],{"class":265},[215,1085,1086],{"class":317},"revenue",[215,1088,288],{"class":261},[215,1090,389],{"class":265},[215,1092,330],{"class":224},[215,1094,314],{"class":265},[215,1096,1097],{"class":224},"\"sum\"",[215,1099,363],{"class":265},[215,1101,1102,1105,1108,1110,1112,1115,1118,1120,1122,1125,1127],{"class":47,"line":384},[215,1103,1104],{"class":265},"summary[",[215,1106,1107],{"class":224},"\"revenue_share\"",[215,1109,444],{"class":265},[215,1111,288],{"class":261},[215,1113,1114],{"class":265}," (summary[",[215,1116,1117],{"class":224},"\"revenue\"",[215,1119,444],{"class":265},[215,1121,455],{"class":261},[215,1123,1124],{"class":265}," total).round(",[215,1126,134],{"class":323},[215,1128,297],{"class":265},[215,1130,1132,1134,1137,1139,1141,1143,1145,1147,1149,1151,1154,1156,1158,1160,1162,1164],{"class":47,"line":1131},8,[215,1133,369],{"class":323},[215,1135,1136],{"class":265},"(by_customer[[",[215,1138,311],{"class":224},[215,1140,314],{"class":265},[215,1142,330],{"class":224},[215,1144,314],{"class":265},[215,1146,465],{"class":224},[215,1148,314],{"class":265},[215,1150,992],{"class":224},[215,1152,1153],{"class":265},"]].round(",[215,1155,134],{"class":323},[215,1157,548],{"class":265},[215,1159,375],{"class":317},[215,1161,288],{"class":261},[215,1163,324],{"class":323},[215,1165,363],{"class":265},[215,1167,1169,1171],{"class":47,"line":1168},9,[215,1170,369],{"class":323},[215,1172,1173],{"class":265},"(summary)\n",[10,1175,1176,1177,1181,1182,1185],{},"Three A customers carry 85% of revenue, two B customers the next 10%, and five C customers the last 5%. The 80\u002F95 thresholds are a convention; inventory planners often use 70\u002F90, and some teams set the cut-offs by count instead of value. Keep the thresholds as named constants so the rule is visible and easy to change. ",[14,1178,1180],{"href":1179},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fexcel-if-formulas-as-pandas-conditional-columns\u002F","Excel IF Formulas as pandas Conditional Columns"," covers ",[212,1183,1184],{},"np.select"," in more detail.",[200,1187,1189],{"id":1188},"step-5-write-the-table-and-a-native-pareto-chart","Step 5 — Write the table and a native Pareto chart",[10,1191,1192],{},"A Pareto chart combines columns for the sorted amounts with a line for the cumulative share on a secondary axis. openpyxl builds both as native Excel charts that readers can restyle:",[205,1194,1196],{"className":252,"code":1195,"language":254,"meta":210,"style":210},"from openpyxl import load_workbook\nfrom openpyxl.chart import BarChart, LineChart, Reference\n\nout = by_customer[[\"customer\", \"amount\", \"cum_share\", \"class\"]]\nout.to_excel(\"pareto.xlsx\", index=False, sheet_name=\"Pareto\")\nwb = load_workbook(\"pareto.xlsx\")\nws = wb[\"Pareto\"]\nn = len(out) + 1\nfor (cell,) in ws.iter_rows(min_row=2, min_col=3, max_col=3):\n    cell.number_format = \"0%\"\n\nbars = BarChart()\nbars.x_axis.delete = False  # Excel hides axes unless this is set\nbars.y_axis.delete = False\nbars.title = \"Revenue by customer\"\nbars.add_data(Reference(ws, min_col=2, min_row=1, max_row=n), titles_from_data=True)\nbars.set_categories(Reference(ws, min_col=1, min_row=2, max_row=n))\nbars.y_axis.title = \"Revenue\"\n\nline = LineChart()\nline.x_axis.delete = False\nline.y_axis.delete = False\nline.add_data(Reference(ws, min_col=3, min_row=1, max_row=n), titles_from_data=True)\nline.y_axis.axId = 200\nline.y_axis.title = \"Cumulative share\"\nline.y_axis.number_format = \"0%\"\nline.y_axis.scaling.max = 1\nline.y_axis.crosses = \"max\"\n\nbars += line\nbars.width, bars.height = 22, 11\nws.add_chart(bars, \"F2\")\nwb.save(\"pareto.xlsx\")\nprint(len(load_workbook(\"pareto.xlsx\")[\"Pareto\"]._charts), \"chart\")\n",[212,1197,1198,1211,1223,1227,1254,1282,1296,1310,1327,1369,1380,1385,1396,1411,1422,1433,1472,1501,1512,1517,1528,1538,1548,1584,1595,1606,1616,1626,1637,1642,1653,1669,1680,1690],{"__ignoreMap":210},[215,1199,1200,1203,1206,1208],{"class":47,"line":217},[215,1201,1202],{"class":261},"from",[215,1204,1205],{"class":265}," openpyxl ",[215,1207,262],{"class":261},[215,1209,1210],{"class":265}," load_workbook\n",[215,1212,1213,1215,1218,1220],{"class":47,"line":275},[215,1214,1202],{"class":261},[215,1216,1217],{"class":265}," openpyxl.chart ",[215,1219,262],{"class":261},[215,1221,1222],{"class":265}," BarChart, LineChart, Reference\n",[215,1224,1225],{"class":47,"line":282},[215,1226,279],{"emptyLinePlaceholder":278},[215,1228,1229,1232,1234,1237,1239,1241,1243,1245,1247,1249,1251],{"class":47,"line":300},[215,1230,1231],{"class":265},"out ",[215,1233,288],{"class":261},[215,1235,1236],{"class":265}," by_customer[[",[215,1238,311],{"class":224},[215,1240,314],{"class":265},[215,1242,330],{"class":224},[215,1244,314],{"class":265},[215,1246,465],{"class":224},[215,1248,314],{"class":265},[215,1250,992],{"class":224},[215,1252,1253],{"class":265},"]]\n",[215,1255,1256,1259,1262,1264,1266,1268,1270,1272,1275,1277,1280],{"class":47,"line":336},[215,1257,1258],{"class":265},"out.to_excel(",[215,1260,1261],{"class":224},"\"pareto.xlsx\"",[215,1263,314],{"class":265},[215,1265,375],{"class":317},[215,1267,288],{"class":261},[215,1269,324],{"class":323},[215,1271,314],{"class":265},[215,1273,1274],{"class":317},"sheet_name",[215,1276,288],{"class":261},[215,1278,1279],{"class":224},"\"Pareto\"",[215,1281,297],{"class":265},[215,1283,1284,1287,1289,1292,1294],{"class":47,"line":366},[215,1285,1286],{"class":265},"wb ",[215,1288,288],{"class":261},[215,1290,1291],{"class":265}," load_workbook(",[215,1293,1261],{"class":224},[215,1295,297],{"class":265},[215,1297,1298,1301,1303,1306,1308],{"class":47,"line":384},[215,1299,1300],{"class":265},"ws ",[215,1302,288],{"class":261},[215,1304,1305],{"class":265}," wb[",[215,1307,1279],{"class":224},[215,1309,616],{"class":265},[215,1311,1312,1315,1317,1319,1322,1324],{"class":47,"line":1131},[215,1313,1314],{"class":265},"n ",[215,1316,288],{"class":261},[215,1318,533],{"class":323},[215,1320,1321],{"class":265},"(out) ",[215,1323,506],{"class":261},[215,1325,1326],{"class":323}," 1\n",[215,1328,1329,1332,1335,1338,1341,1344,1346,1348,1350,1353,1355,1357,1359,1362,1364,1366],{"class":47,"line":1168},[215,1330,1331],{"class":261},"for",[215,1333,1334],{"class":265}," (cell,) ",[215,1336,1337],{"class":261},"in",[215,1339,1340],{"class":265}," ws.iter_rows(",[215,1342,1343],{"class":317},"min_row",[215,1345,288],{"class":261},[215,1347,859],{"class":323},[215,1349,314],{"class":265},[215,1351,1352],{"class":317},"min_col",[215,1354,288],{"class":261},[215,1356,134],{"class":323},[215,1358,314],{"class":265},[215,1360,1361],{"class":317},"max_col",[215,1363,288],{"class":261},[215,1365,134],{"class":323},[215,1367,1368],{"class":265},"):\n",[215,1370,1372,1375,1377],{"class":47,"line":1371},10,[215,1373,1374],{"class":265},"    cell.number_format ",[215,1376,288],{"class":261},[215,1378,1379],{"class":224}," \"0%\"\n",[215,1381,1383],{"class":47,"line":1382},11,[215,1384,279],{"emptyLinePlaceholder":278},[215,1386,1388,1391,1393],{"class":47,"line":1387},12,[215,1389,1390],{"class":265},"bars ",[215,1392,288],{"class":261},[215,1394,1395],{"class":265}," BarChart()\n",[215,1397,1399,1402,1404,1407],{"class":47,"line":1398},13,[215,1400,1401],{"class":265},"bars.x_axis.delete ",[215,1403,288],{"class":261},[215,1405,1406],{"class":323}," False",[215,1408,1410],{"class":1409},"s-wDw","  # Excel hides axes unless this is set\n",[215,1412,1414,1417,1419],{"class":47,"line":1413},14,[215,1415,1416],{"class":265},"bars.y_axis.delete ",[215,1418,288],{"class":261},[215,1420,1421],{"class":323}," False\n",[215,1423,1425,1428,1430],{"class":47,"line":1424},15,[215,1426,1427],{"class":265},"bars.title ",[215,1429,288],{"class":261},[215,1431,1432],{"class":224}," \"Revenue by customer\"\n",[215,1434,1436,1439,1441,1443,1445,1447,1449,1451,1453,1455,1458,1460,1463,1466,1468,1470],{"class":47,"line":1435},16,[215,1437,1438],{"class":265},"bars.add_data(Reference(ws, ",[215,1440,1352],{"class":317},[215,1442,288],{"class":261},[215,1444,859],{"class":323},[215,1446,314],{"class":265},[215,1448,1343],{"class":317},[215,1450,288],{"class":261},[215,1452,495],{"class":323},[215,1454,314],{"class":265},[215,1456,1457],{"class":317},"max_row",[215,1459,288],{"class":261},[215,1461,1462],{"class":265},"n), ",[215,1464,1465],{"class":317},"titles_from_data",[215,1467,288],{"class":261},[215,1469,360],{"class":323},[215,1471,297],{"class":265},[215,1473,1475,1478,1480,1482,1484,1486,1488,1490,1492,1494,1496,1498],{"class":47,"line":1474},17,[215,1476,1477],{"class":265},"bars.set_categories(Reference(ws, ",[215,1479,1352],{"class":317},[215,1481,288],{"class":261},[215,1483,495],{"class":323},[215,1485,314],{"class":265},[215,1487,1343],{"class":317},[215,1489,288],{"class":261},[215,1491,859],{"class":323},[215,1493,314],{"class":265},[215,1495,1457],{"class":317},[215,1497,288],{"class":261},[215,1499,1500],{"class":265},"n))\n",[215,1502,1504,1507,1509],{"class":47,"line":1503},18,[215,1505,1506],{"class":265},"bars.y_axis.title ",[215,1508,288],{"class":261},[215,1510,1511],{"class":224}," \"Revenue\"\n",[215,1513,1515],{"class":47,"line":1514},19,[215,1516,279],{"emptyLinePlaceholder":278},[215,1518,1520,1523,1525],{"class":47,"line":1519},20,[215,1521,1522],{"class":265},"line ",[215,1524,288],{"class":261},[215,1526,1527],{"class":265}," LineChart()\n",[215,1529,1531,1534,1536],{"class":47,"line":1530},21,[215,1532,1533],{"class":265},"line.x_axis.delete ",[215,1535,288],{"class":261},[215,1537,1421],{"class":323},[215,1539,1541,1544,1546],{"class":47,"line":1540},22,[215,1542,1543],{"class":265},"line.y_axis.delete ",[215,1545,288],{"class":261},[215,1547,1421],{"class":323},[215,1549,1551,1554,1556,1558,1560,1562,1564,1566,1568,1570,1572,1574,1576,1578,1580,1582],{"class":47,"line":1550},23,[215,1552,1553],{"class":265},"line.add_data(Reference(ws, ",[215,1555,1352],{"class":317},[215,1557,288],{"class":261},[215,1559,134],{"class":323},[215,1561,314],{"class":265},[215,1563,1343],{"class":317},[215,1565,288],{"class":261},[215,1567,495],{"class":323},[215,1569,314],{"class":265},[215,1571,1457],{"class":317},[215,1573,288],{"class":261},[215,1575,1462],{"class":265},[215,1577,1465],{"class":317},[215,1579,288],{"class":261},[215,1581,360],{"class":323},[215,1583,297],{"class":265},[215,1585,1587,1590,1592],{"class":47,"line":1586},24,[215,1588,1589],{"class":265},"line.y_axis.axId ",[215,1591,288],{"class":261},[215,1593,1594],{"class":323}," 200\n",[215,1596,1598,1601,1603],{"class":47,"line":1597},25,[215,1599,1600],{"class":265},"line.y_axis.title ",[215,1602,288],{"class":261},[215,1604,1605],{"class":224}," \"Cumulative share\"\n",[215,1607,1609,1612,1614],{"class":47,"line":1608},26,[215,1610,1611],{"class":265},"line.y_axis.number_format ",[215,1613,288],{"class":261},[215,1615,1379],{"class":224},[215,1617,1619,1622,1624],{"class":47,"line":1618},27,[215,1620,1621],{"class":265},"line.y_axis.scaling.max ",[215,1623,288],{"class":261},[215,1625,1326],{"class":323},[215,1627,1629,1632,1634],{"class":47,"line":1628},28,[215,1630,1631],{"class":265},"line.y_axis.crosses ",[215,1633,288],{"class":261},[215,1635,1636],{"class":224}," \"max\"\n",[215,1638,1640],{"class":47,"line":1639},29,[215,1641,279],{"emptyLinePlaceholder":278},[215,1643,1645,1647,1650],{"class":47,"line":1644},30,[215,1646,1390],{"class":265},[215,1648,1649],{"class":261},"+=",[215,1651,1652],{"class":265}," line\n",[215,1654,1656,1659,1661,1664,1666],{"class":47,"line":1655},31,[215,1657,1658],{"class":265},"bars.width, bars.height ",[215,1660,288],{"class":261},[215,1662,1663],{"class":323}," 22",[215,1665,314],{"class":265},[215,1667,1668],{"class":323},"11\n",[215,1670,1672,1675,1678],{"class":47,"line":1671},32,[215,1673,1674],{"class":265},"ws.add_chart(bars, ",[215,1676,1677],{"class":224},"\"F2\"",[215,1679,297],{"class":265},[215,1681,1683,1686,1688],{"class":47,"line":1682},33,[215,1684,1685],{"class":265},"wb.save(",[215,1687,1261],{"class":224},[215,1689,297],{"class":265},[215,1691,1693,1695,1697,1699,1702,1704,1706,1708,1711,1714],{"class":47,"line":1692},34,[215,1694,369],{"class":323},[215,1696,389],{"class":265},[215,1698,500],{"class":323},[215,1700,1701],{"class":265},"(load_workbook(",[215,1703,1261],{"class":224},[215,1705,327],{"class":265},[215,1707,1279],{"class":224},[215,1709,1710],{"class":265},"]._charts), ",[215,1712,1713],{"class":224},"\"chart\"",[215,1715,297],{"class":265},[10,1717,1718,1719,1723],{},"Giving the line its own axis id and setting it to cross at the maximum puts the cumulative scale on the right-hand side, fixed from 0 to 100%. The chart reads its data from the cells, so if the table is refreshed with next month's figures in the same place, the chart follows. ",[14,1720,1722],{"href":1721},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fadd-a-combo-chart-with-a-secondary-axis-in-openpyxl\u002F","Add a Combo Chart with a Secondary Axis in openpyxl"," explains the axis settings in depth.",[20,1725,29,1731,29,1734,29,1737,29,1741,29,1746,29,1751,29,1757,29,1760,29,1764,29,1767,29,1771,29,1774,29,1778,29,1780,29,1783,29,1785,29,1787,29,1789,29,1792,29,1795,29,1798,29,1800,29,1803,29,1805,29,1808,29,1810,29,1813,29,1816,29,1819,29,1821,29,1824,29,1826,29,1829,29,1831],{"viewBox":1726,"role":23,"ariaLabelledBy":1727,"xmlns":27,"style":1730},"4 0 752 174",[1728,1729],"par-abc-t","par-abc-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[31,1732,1733],{"id":1728},"The ABC classes for the ten customers",[35,1735,1736],{"id":1729},"A summary of the ABC classification. Class A has three customers and 85% of revenue. Class B has two customers and 10%. Class C has five customers and 5%. The thresholds were 80% and 95% of cumulative revenue.",[39,1738],{"x":41,"y":42,"width":1739,"height":1740,"fill":45},"752","174",[39,1742],{"x":184,"y":1743,"width":1744,"height":1745,"rx":42,"fill":45,"stroke":52,"style":53},"16.0","37.8","40.0",[39,1747],{"x":1748,"y":1743,"width":1749,"height":1745,"rx":42,"fill":135,"stroke":136,"style":1750},"57.8","227.4","stroke-width:1.2px",[55,1752,1756],{"x":1753,"y":1754,"style":1755},"171.5","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Customers",[39,1758],{"x":1759,"y":1743,"width":1749,"height":1745,"rx":42,"fill":135,"stroke":136,"style":1750},"285.2",[55,1761,1763],{"x":1762,"y":1754,"style":1755},"398.9","Revenue share",[39,1765],{"x":1766,"y":1743,"width":1749,"height":1745,"rx":42,"fill":135,"stroke":136,"style":1750},"512.6",[55,1768,1770],{"x":1769,"y":1754,"style":1755},"626.3","Rule",[39,1772],{"x":184,"y":1773,"width":1744,"height":146,"rx":42,"fill":792,"stroke":52,"style":53},"56.0",[55,1775,802],{"x":791,"y":1776,"style":1777},"78.0","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start",[39,1779],{"x":1748,"y":1773,"width":1749,"height":146,"rx":42,"fill":45,"stroke":52,"style":53},[55,1781,134],{"x":1753,"y":1782,"style":90},"77.0",[39,1784],{"x":1759,"y":1773,"width":1749,"height":146,"rx":42,"fill":45,"stroke":52,"style":53},[55,1786,924],{"x":1762,"y":1782,"style":90},[39,1788],{"x":1766,"y":1773,"width":1749,"height":146,"rx":42,"fill":45,"stroke":52,"style":53},[55,1790,1791],{"x":1769,"y":1782,"style":90},"prev_cum \u003C 80%",[39,1793],{"x":184,"y":1794,"width":1744,"height":146,"rx":42,"fill":792,"stroke":52,"style":53},"90.0",[55,1796,810],{"x":791,"y":1797,"style":1777},"112.0",[39,1799],{"x":1748,"y":1794,"width":1749,"height":146,"rx":42,"fill":45,"stroke":52,"style":53},[55,1801,859],{"x":1753,"y":1802,"style":90},"111.0",[39,1804],{"x":1759,"y":1794,"width":1749,"height":146,"rx":42,"fill":45,"stroke":52,"style":53},[55,1806,1807],{"x":1762,"y":1802,"style":90},"10%",[39,1809],{"x":1766,"y":1794,"width":1749,"height":146,"rx":42,"fill":45,"stroke":52,"style":53},[55,1811,1812],{"x":1769,"y":1802,"style":90},"prev_cum \u003C 95%",[39,1814],{"x":184,"y":1815,"width":1744,"height":146,"rx":42,"fill":792,"stroke":52,"style":53},"124.0",[55,1817,818],{"x":791,"y":1818,"style":1777},"146.0",[39,1820],{"x":1748,"y":1815,"width":1749,"height":146,"rx":42,"fill":45,"stroke":52,"style":53},[55,1822,938],{"x":1753,"y":1823,"style":90},"145.0",[39,1825],{"x":1759,"y":1815,"width":1749,"height":146,"rx":42,"fill":45,"stroke":52,"style":53},[55,1827,1828],{"x":1762,"y":1823,"style":90},"5%",[39,1830],{"x":1766,"y":1815,"width":1749,"height":146,"rx":42,"fill":45,"stroke":52,"style":53},[55,1832,1833],{"x":1769,"y":1823,"style":90},"the rest",[200,1835,1837],{"id":1836},"say-it-in-one-sentence","Say it in one sentence",[10,1839,1840],{},"The table and chart are for analysts; the people who act on a Pareto analysis usually want one line in an email or at the top of a dashboard. Generate it from the same numbers, so it can never disagree with the table:",[205,1842,1844],{"className":252,"code":1843,"language":254,"meta":210,"style":210},"n_top, n_all = len(top), len(by_customer)\nsentence = (f\"{n_top} of {n_all} customers ({n_top \u002F n_all:.0%}) bring \"\n            f\"{top['cum_share'].iloc[-1]:.0%} of revenue: {', '.join(top['customer'])}.\")\nprint(sentence)\n",[212,1845,1846,1861,1918,1970],{"__ignoreMap":210},[215,1847,1848,1851,1853,1855,1857,1859],{"class":47,"line":217},[215,1849,1850],{"class":265},"n_top, n_all ",[215,1852,288],{"class":261},[215,1854,533],{"class":323},[215,1856,649],{"class":265},[215,1858,500],{"class":323},[215,1860,536],{"class":265},[215,1862,1863,1866,1868,1871,1874,1877,1881,1884,1887,1890,1892,1895,1897,1900,1902,1905,1907,1910,1913,1915],{"class":47,"line":275},[215,1864,1865],{"class":265},"sentence ",[215,1867,288],{"class":261},[215,1869,1870],{"class":265}," (",[215,1872,1873],{"class":261},"f",[215,1875,1876],{"class":224},"\"",[215,1878,1880],{"class":1879},"sSjpA","{",[215,1882,1883],{"class":265},"n_top",[215,1885,1886],{"class":1879},"}",[215,1888,1889],{"class":224}," of ",[215,1891,1880],{"class":1879},[215,1893,1894],{"class":265},"n_all",[215,1896,1886],{"class":1879},[215,1898,1899],{"class":224}," customers (",[215,1901,1880],{"class":1879},[215,1903,1904],{"class":265},"n_top ",[215,1906,455],{"class":261},[215,1908,1909],{"class":265}," n_all",[215,1911,1912],{"class":261},":.0%",[215,1914,1886],{"class":1879},[215,1916,1917],{"class":224},") bring \"\n",[215,1919,1920,1923,1925,1927,1930,1933,1935,1937,1939,1942,1944,1946,1949,1951,1954,1957,1960,1963,1965,1968],{"class":47,"line":282},[215,1921,1922],{"class":261},"            f",[215,1924,1876],{"class":224},[215,1926,1880],{"class":1879},[215,1928,1929],{"class":265},"top[",[215,1931,1932],{"class":224},"'cum_share'",[215,1934,665],{"class":265},[215,1936,609],{"class":261},[215,1938,495],{"class":323},[215,1940,1941],{"class":265},"]",[215,1943,1912],{"class":261},[215,1945,1886],{"class":1879},[215,1947,1948],{"class":224}," of revenue: ",[215,1950,1880],{"class":1879},[215,1952,1953],{"class":224},"', '",[215,1955,1956],{"class":265},".join(top[",[215,1958,1959],{"class":224},"'customer'",[215,1961,1962],{"class":265},"])",[215,1964,1886],{"class":1879},[215,1966,1967],{"class":224},".\"",[215,1969,297],{"class":265},[215,1971,1972,1974],{"class":47,"line":300},[215,1973,369],{"class":323},[215,1975,1976],{"class":265},"(sentence)\n",[10,1978,1979],{},"\"3 of 10 customers (30%) bring 85% of revenue: Northwind, Contoso, Fabrikam.\" Written to a cell above the table or into the body of the report email, it states the finding in the terms readers already use, and it updates itself on the next run.",[200,1981,1983],{"id":1982},"step-6-run-it-per-group","Step 6 — Run it per group",[10,1985,1986,1987,1990],{},"Pareto questions are often asked within a segment — which products make up 80% of each region's sales. Compute the cumulative share inside each group by sorting within groups and using ",[212,1988,1989],{},"groupby().cumsum()",":",[205,1992,1994],{"className":252,"code":1993,"language":254,"meta":210,"style":210},"orders[\"region\"] = [\"North\" if i % 3 else \"South\" for i in range(len(orders))]\nper = (orders.groupby([\"region\", \"customer\"], as_index=False)[\"amount\"].sum()\n             .sort_values([\"region\", \"amount\"], ascending=[True, False]))\nper[\"share\"] = per[\"amount\"] \u002F per.groupby(\"region\")[\"amount\"].transform(\"sum\")\nper[\"prev_cum\"] = per.groupby(\"region\")[\"share\"].cumsum() - per[\"share\"]\nprint(per[per[\"prev_cum\"] \u003C 0.8].groupby(\"region\")[\"customer\"].count().to_dict())\n",[212,1995,1996,2048,2078,2107,2143,2172],{"__ignoreMap":210},[215,1997,1998,2001,2004,2006,2008,2011,2014,2017,2020,2023,2026,2029,2032,2035,2037,2039,2041,2043,2045],{"class":47,"line":217},[215,1999,2000],{"class":265},"orders[",[215,2002,2003],{"class":224},"\"region\"",[215,2005,444],{"class":265},[215,2007,288],{"class":261},[215,2009,2010],{"class":265}," [",[215,2012,2013],{"class":224},"\"North\"",[215,2015,2016],{"class":261}," if",[215,2018,2019],{"class":265}," i ",[215,2021,2022],{"class":261},"%",[215,2024,2025],{"class":323}," 3",[215,2027,2028],{"class":261}," else",[215,2030,2031],{"class":224}," \"South\"",[215,2033,2034],{"class":261}," for",[215,2036,2019],{"class":265},[215,2038,1337],{"class":261},[215,2040,490],{"class":323},[215,2042,389],{"class":265},[215,2044,500],{"class":323},[215,2046,2047],{"class":265},"(orders))]\n",[215,2049,2050,2053,2055,2058,2060,2062,2064,2066,2068,2070,2072,2074,2076],{"class":47,"line":275},[215,2051,2052],{"class":265},"per ",[215,2054,288],{"class":261},[215,2056,2057],{"class":265}," (orders.groupby([",[215,2059,2003],{"class":224},[215,2061,314],{"class":265},[215,2063,311],{"class":224},[215,2065,672],{"class":265},[215,2067,318],{"class":317},[215,2069,288],{"class":261},[215,2071,324],{"class":323},[215,2073,327],{"class":265},[215,2075,330],{"class":224},[215,2077,333],{"class":265},[215,2079,2080,2083,2085,2087,2089,2091,2093,2095,2098,2100,2102,2104],{"class":47,"line":282},[215,2081,2082],{"class":265},"             .sort_values([",[215,2084,2003],{"class":224},[215,2086,314],{"class":265},[215,2088,330],{"class":224},[215,2090,672],{"class":265},[215,2092,346],{"class":317},[215,2094,288],{"class":261},[215,2096,2097],{"class":265},"[",[215,2099,360],{"class":323},[215,2101,314],{"class":265},[215,2103,324],{"class":323},[215,2105,2106],{"class":265},"]))\n",[215,2108,2109,2112,2114,2116,2118,2121,2123,2125,2127,2130,2132,2134,2136,2139,2141],{"class":47,"line":300},[215,2110,2111],{"class":265},"per[",[215,2113,441],{"class":224},[215,2115,444],{"class":265},[215,2117,288],{"class":261},[215,2119,2120],{"class":265}," per[",[215,2122,330],{"class":224},[215,2124,444],{"class":265},[215,2126,455],{"class":261},[215,2128,2129],{"class":265}," per.groupby(",[215,2131,2003],{"class":224},[215,2133,327],{"class":265},[215,2135,330],{"class":224},[215,2137,2138],{"class":265},"].transform(",[215,2140,1097],{"class":224},[215,2142,297],{"class":265},[215,2144,2145,2147,2149,2151,2153,2155,2157,2159,2161,2164,2166,2168,2170],{"class":47,"line":336},[215,2146,2111],{"class":265},[215,2148,596],{"class":224},[215,2150,444],{"class":265},[215,2152,288],{"class":261},[215,2154,2129],{"class":265},[215,2156,2003],{"class":224},[215,2158,327],{"class":265},[215,2160,441],{"class":224},[215,2162,2163],{"class":265},"].cumsum() ",[215,2165,609],{"class":261},[215,2167,2120],{"class":265},[215,2169,441],{"class":224},[215,2171,616],{"class":265},[215,2173,2174,2176,2179,2181,2183,2185,2187,2190,2192,2194,2196],{"class":47,"line":366},[215,2175,369],{"class":323},[215,2177,2178],{"class":265},"(per[per[",[215,2180,596],{"class":224},[215,2182,444],{"class":265},[215,2184,633],{"class":261},[215,2186,636],{"class":323},[215,2188,2189],{"class":265},"].groupby(",[215,2191,2003],{"class":224},[215,2193,327],{"class":265},[215,2195,311],{"class":224},[215,2197,2198],{"class":265},"].count().to_dict())\n",[10,2200,2201,2202,2205,2206,2210,2211,2214],{},"Each region gets its own count of customers needed to reach 80% of ",[246,2203,2204],{},"its"," revenue. ",[14,2207,2209],{"href":2208},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fcalculate-percent-of-total-per-group-in-pandas\u002F","Calculate Percent of Total per Group in pandas"," explains the ",[212,2212,2213],{},"transform"," pattern used for the group shares.",[200,2216,2218],{"id":2217},"common-pitfalls","Common pitfalls",[2220,2221,2222,2230,2238,2244],"ul",{},[2223,2224,2225,2229],"li",{},[2226,2227,2228],"strong",{},"Ranking rows instead of items."," Aggregate by customer or product first.",[2223,2231,2232,2237],{},[2226,2233,2234,2236],{},[212,2235,576],{},"."," It excludes the item that crosses the line; use the cumulative share before the item.",[2223,2239,2240,2243],{},[2226,2241,2242],{},"Forcing the 80\u002F20 story."," Report the actual split — \"30% of customers, 85% of revenue\".",[2223,2245,2246,2249],{},[2226,2247,2248],{},"Negative amounts."," Credit notes can make shares exceed 100% part-way; net them per item before ranking.",[200,2251,2253],{"id":2252},"performance-notes","Performance notes",[10,2255,2256,2257,2260],{},"Grouping, sorting and ",[212,2258,2259],{},"cumsum"," are all vectorised; a Pareto table over millions of rows takes well under a second. The chart is the slowest part of the job and still negligible. Charts with thousands of categories are unreadable, so for long tails chart the A and B items and show C as a single bar.",[200,2262,2264],{"id":2263},"conclusion","Conclusion",[10,2266,2267,2268,2270,2271,2273,2274,2276],{},"Aggregate to one row per item, sort descending, compute each item's share and the running share with ",[212,2269,2259],{},", and count the items needed for 80% using the cumulative share ",[246,2272,580],{}," each item so the crossing item is included. Extend the same rule to A\u002FB\u002FC classes, write the table with a native Pareto chart — columns plus a cumulative line on a secondary axis — and run it within groups with ",[212,2275,1989],{}," when the question is asked per segment.",[200,2278,2280],{"id":2279},"frequently-asked-questions","Frequently asked questions",[10,2282,2283,2286],{},[2226,2284,2285],{},"What is a Pareto analysis?","\nIt ranks items by their contribution to a total and shows the cumulative share, to find the few items that account for most of it — often around 80% of revenue from about 20% of customers, though the actual split varies.",[10,2288,2289,2292],{},[2226,2290,2291],{},"Is the item that crosses 80% in the top group?","\nIt should be. The items needed to reach 80% include the one that takes the running total past the line. Classify on the cumulative share before the item is added — prev_cum \u003C 0.8 — so the crossing item counts as A.",[10,2294,2295,2298],{},[2226,2296,2297],{},"What is ABC classification?","\nA three-tier version of the same idea: A items make up the first 80% of the total, B items the next 15%, and C items the last 5%. The thresholds are conventions; inventory teams often use 70\u002F20\u002F10 instead.",[10,2300,2301,2304],{},[2226,2302,2303],{},"How do I make a Pareto chart in Excel from Python?","\nWrite the sorted amounts and the cumulative share, then build a bar chart of the amounts and a line chart of the cumulative share on a secondary axis with openpyxl, and combine them.",[200,2306,2308],{"id":2307},"related","Related",[2220,2310,2311,2317,2324,2331],{},[2223,2312,2313,2314,2316],{},"Up one level: ",[14,2315,17],{"href":16}," — pivots, subtotals and exports.",[2223,2318,2319,2323],{},[14,2320,2322],{"href":2321},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Frunning-totals-and-year-over-year-growth-in-pandas\u002F","Running Totals and Year-Over-Year Growth in pandas"," — cumulative sums over time.",[2223,2325,2326,2330],{},[14,2327,2329],{"href":2328},"\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"," — a fixed count instead of a share.",[2223,2332,2333,2337],{},[14,2334,2336],{"href":2335},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fstyle-chart-colors-and-data-labels-with-openpyxl\u002F","Style Chart Colours and Data Labels with openpyxl"," — finishing the chart.",[2339,2340,2341],"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 .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}",{"title":210,"searchDepth":275,"depth":275,"links":2343},[2344,2345,2346,2347,2348,2349,2350,2351,2352,2353,2354,2355,2356],{"id":202,"depth":275,"text":203},{"id":240,"depth":275,"text":241},{"id":410,"depth":275,"text":411},{"id":569,"depth":275,"text":570},{"id":960,"depth":275,"text":961},{"id":1188,"depth":275,"text":1189},{"id":1836,"depth":275,"text":1837},{"id":1982,"depth":275,"text":1983},{"id":2217,"depth":275,"text":2218},{"id":2252,"depth":275,"text":2253},{"id":2263,"depth":275,"text":2264},{"id":2279,"depth":275,"text":2280},{"id":2307,"depth":275,"text":2308},"2026-09-25","Find the handful of customers or products that make up 80% of revenue. Aggregate, sort, compute cumulative shares, classify items into A, B and C with a clear rule for the item that crosses each threshold, and write the table with a native Excel Pareto chart — columns plus a cumulative line on a secondary axis.","md",[2361,2363,2365,2367],{"q":2285,"a":2362},"It ranks items by their contribution to a total and shows the cumulative share, to find the few items that account for most of it — often around 80% of revenue from about 20% of customers, though the actual split varies.",{"q":2291,"a":2364},"It should be. The items needed to reach 80% include the one that takes the running total past the line. Classify on the cumulative share before the item is added — prev_cum \u003C 0.8 — so the crossing item counts as A.",{"q":2297,"a":2366},"A three-tier version of the same idea: A items make up the first 80% of the total, B items the next 15%, and C items the last 5%. The thresholds are conventions; inventory teams often use 70\u002F20\u002F10 instead.",{"q":2303,"a":2368},"Write the sorted amounts and the cumulative share, then build a bar chart of the amounts and a line chart of the cumulative share on a secondary axis with openpyxl, and combine them.","pareto analysis with cumulative percent in pandas",null,{"breadcrumb":2372},[2373,2375,2378],{"name":2374,"item":455},"Home",{"name":2376,"item":2377},"Advanced Data Transformation and Cleaning for Excel Automation","\u002Fadvanced-data-transformation-and-cleaning\u002F",{"name":17,"item":16},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Frun-a-pareto-analysis-on-excel-data-with-pandas",{"title":2381,"description":2382},"Pareto (80\u002F20) and ABC Analysis of Excel Data in pandas","Pareto analysis in pandas: aggregate and sort, cumsum for cumulative share, how many items make 80%, ABC classification with the boundary item handled correctly, and a Pareto chart in Excel with openpyxl.","run-a-pareto-analysis-on-excel-data-with-pandas","advanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Frun-a-pareto-analysis-on-excel-data-with-pandas\u002Findex",[2386,2387,2388],"pivots-and-summaries","charts-and-images","pandas","how-to","Z9ivL1-EbIIz3FeY1y-XHmSImHyF_JClDpKgnCF8-jo",[2392,2396],{"title":2393,"path":2394,"stem":2395,"children":-1},"Pivot Text Values Instead of Numbers in pandas","\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fpivot-text-values-instead-of-numbers-in-pandas","advanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fpivot-text-values-instead-of-numbers-in-pandas\u002Findex",{"title":2397,"path":2398,"stem":2399,"children":-1},"Run an ABC-XYZ Inventory Classification","\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Frun-an-abc-xyz-inventory-classification","advanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Frun-an-abc-xyz-inventory-classification\u002Findex",[2401,2403],{"path":2402,"title":17},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data",{"path":2404,"title":2376},"\u002Fadvanced-data-transformation-and-cleaning",[],[2407,2410,2413,2416,2419,2422],{"path":2408,"title":2409,"kind":2389},"\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":2411,"title":2412,"kind":2389},"\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":2414,"title":2415,"kind":2389},"\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":2417,"title":2418,"kind":2389},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fadd-subtotals-and-grand-totals-to-a-pandas-pivot-table","Add Subtotals and Grand Totals to a pandas Pivot Table",{"path":2420,"title":2421,"kind":2389},"\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":2423,"title":2424,"kind":2389},"\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",1790972086593]