[{"data":1,"prerenderedAt":2290},["ShallowReactive",2],{"doc:\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fclean-and-aggregate-excel-data-with-polars":3,"surround:\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fclean-and-aggregate-excel-data-with-polars":2260,"ancestors:\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fclean-and-aggregate-excel-data-with-polars":2268,"children:\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fclean-and-aggregate-excel-data-with-polars":2272,"related:\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fclean-and-aggregate-excel-data-with-polars":2273},{"id":4,"title":5,"body":6,"dateModified":2227,"datePublished":2227,"description":2228,"extension":2229,"faq":2230,"keyword":2239,"kind":2240,"meta":2241,"navigation":455,"path":2249,"seo":2250,"slug":2252,"stem":2253,"topics":2254,"type":2258,"__hash__":2259},"docs\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fclean-and-aggregate-excel-data-with-polars\u002Findex.md","Clean and Aggregate Excel Data with Polars Expressions",{"type":7,"value":8,"toc":2213},"minimark",[9,19,382,387,424,427,804,810,814,817,996,1014,1018,1021,1097,1107,1111,1118,1224,1235,1394,1398,1401,1544,1562,1566,1569,1721,1731,1841,1845,1855,1987,2000,2004,2010,2077,2084,2088,2128,2132,2148,2152,2158,2164,2170,2176,2180,2209],[10,11,12,13,18],"p",{},"A sales export from a regional team arrives with the usual problems: \" north\", \"NORTH \" and \"north\" for the same region, \"tea\" and \"Tea\" for the same product, revenue typed as \"1,200\", \"€ 300\", \"1 050\" and \"n\u002Fa\". Polars can fix all of it in a handful of expressions, and aggregate the result much faster than a pandas loop on large sheets. Expressions also compose: the cleaning rules are values you can store, reuse and apply to every export. This guide, part of ",[14,15,17],"a",{"href":16},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002F","Reading Excel with Polars and Arrow",", goes from the raw sheet to a summary workbook.",[20,21,29,30,29,34,29,38,29,46,29,55,29,59,29,66,29,70,29,74,29,78,29,82,29,86,29,91,29,93,29,97,29,99,29,102,29,104,29,107,29,110,29,114,29,116,29,120,29,122,29,125,29,127,29,130,29,133,29,137,29,139,29,142,29,144,29,147,29,149,29,152,29,155,29,159,29,161,29,164,29,166,29,169,29,171,29,174,29,177,29,181,29,183,29,186,29,188,29,190,29,192,29,195,29,198,29,202,29,204,29,206,29,208,29,210,29,212,29,215,29,218,29,222,29,225,29,229,29,232,29,236,29,239,29,241,29,244,29,246,29,249,29,251,29,254,29,256,29,259,29,261,29,263,29,265,29,268,29,270,29,272,29,274,29,277,29,279,29,281,29,283,29,285,29,287,29,289,29,291,29,294,29,296,29,298,29,300,29,302,29,304,29,306,29,308,29,311,29,313,29,315,29,317,29,320,29,322,29,324,29,326,29,329,29,331,29,333,29,335,29,337,29,339,29,341,29,343,29,346,29,351,29,355,29,363,29,368,29,376],"svg",{"viewBox":22,"role":23,"ariaLabelledBy":24,"xmlns":27,"style":28},"30 0 700 248","img",[25,26],"pc-clean-t","pc-clean-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:700px;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},"The export before and after the cleaning expressions",[35,36,37],"desc",{"id":26},"Before cleaning, regions are written with stray spaces and mixed case, products differ by case, and revenue is text with thousands separators, a euro sign, a space and n\u002Fa. After the expressions, regions and products are in title case and revenue is a number, with n\u002Fa turned into null.",[39,40],"rect",{"x":41,"y":42,"width":43,"height":44,"fill":45},"30","0","700","248","#ffffff",[39,47],{"x":48,"y":49,"width":50,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"46.0","40.0","32.0","24.0","#e7ebef","var(--line,#cdd5e6)","stroke-width:1px",[39,56],{"x":57,"y":49,"width":58,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"78.0","77.0",[60,61,65],"text",{"x":62,"y":63,"style":64},"116.5","57.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[39,67],{"x":68,"y":49,"width":69,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"155.0","72.8",[60,71,73],{"x":72,"y":63,"style":64},"191.4","B",[39,75],{"x":76,"y":49,"width":77,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"227.8","78.1",[60,79,81],{"x":80,"y":63,"style":64},"266.9","C",[39,83],{"x":48,"y":84,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"64.0","28.0",[60,87,90],{"x":88,"y":89,"style":64},"62.0","83.0","1",[39,92],{"x":57,"y":84,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,94,96],{"x":62,"y":89,"style":95},"font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Region",[39,98],{"x":68,"y":84,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,100,101],{"x":72,"y":89,"style":95},"Product",[39,103],{"x":76,"y":84,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,105,106],{"x":80,"y":89,"style":95},"Revenue",[39,108],{"x":48,"y":109,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"92.0",[60,111,113],{"x":88,"y":112,"style":64},"111.0","2",[39,115],{"x":57,"y":109,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,117,119],{"x":62,"y":112,"style":118},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","␠north",[39,121],{"x":68,"y":109,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,123,124],{"x":72,"y":112,"style":118},"Tea",[39,126],{"x":76,"y":109,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,128,129],{"x":80,"y":112,"style":118},"1,200",[39,131],{"x":48,"y":132,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"120.0",[60,134,136],{"x":88,"y":135,"style":64},"139.0","3",[39,138],{"x":57,"y":132,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,140,141],{"x":62,"y":135,"style":118},"South",[39,143],{"x":68,"y":132,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,145,146],{"x":72,"y":135,"style":118},"tea",[39,148],{"x":76,"y":132,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,150,151],{"x":80,"y":135,"style":118},"950",[39,153],{"x":48,"y":154,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"148.0",[60,156,158],{"x":88,"y":157,"style":64},"167.0","4",[39,160],{"x":57,"y":154,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,162,163],{"x":62,"y":157,"style":118},"NORTH␠",[39,165],{"x":68,"y":154,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,167,168],{"x":72,"y":157,"style":118},"Coffee",[39,170],{"x":76,"y":154,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,172,173],{"x":80,"y":157,"style":118},"€ 300",[39,175],{"x":48,"y":176,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"176.0",[60,178,180],{"x":88,"y":179,"style":64},"195.0","5",[39,182],{"x":57,"y":176,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,184,185],{"x":62,"y":179,"style":118},"east",[39,187],{"x":68,"y":176,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,189,124],{"x":72,"y":179,"style":118},[39,191],{"x":76,"y":176,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,193,194],{"x":80,"y":179,"style":118},"n\u002Fa",[39,196],{"x":48,"y":197,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"204.0",[60,199,201],{"x":88,"y":200,"style":64},"223.0","6",[39,203],{"x":57,"y":197,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,205,141],{"x":62,"y":200,"style":118},[39,207],{"x":68,"y":197,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,209,168],{"x":72,"y":200,"style":118},[39,211],{"x":76,"y":197,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,213,214],{"x":80,"y":200,"style":118},"1 050",[39,216],{"x":217,"y":49,"width":50,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"470.9",[39,219],{"x":220,"y":49,"width":221,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"502.9","63.6",[60,223,65],{"x":224,"y":63,"style":64},"534.6",[39,226],{"x":227,"y":49,"width":228,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"566.4","72.6",[60,230,73],{"x":231,"y":63,"style":64},"602.7",[39,233],{"x":234,"y":49,"width":235,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"639.0","74.9",[60,237,81],{"x":238,"y":63,"style":64},"676.5",[39,240],{"x":217,"y":84,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,242,90],{"x":243,"y":89,"style":64},"486.9",[39,245],{"x":220,"y":84,"width":221,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,247,248],{"x":224,"y":89,"style":95},"region",[39,250],{"x":227,"y":84,"width":228,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,252,253],{"x":231,"y":89,"style":95},"product",[39,255],{"x":234,"y":84,"width":235,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,257,258],{"x":238,"y":89,"style":95},"revenue",[39,260],{"x":217,"y":109,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,262,113],{"x":243,"y":112,"style":64},[39,264],{"x":220,"y":109,"width":221,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,266,267],{"x":224,"y":112,"style":118},"North",[39,269],{"x":227,"y":109,"width":228,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,271,124],{"x":231,"y":112,"style":118},[39,273],{"x":234,"y":109,"width":235,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,275,276],{"x":238,"y":112,"style":118},"1200.0",[39,278],{"x":217,"y":132,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,280,136],{"x":243,"y":135,"style":64},[39,282],{"x":220,"y":132,"width":221,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,284,141],{"x":224,"y":135,"style":118},[39,286],{"x":227,"y":132,"width":228,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,288,124],{"x":231,"y":135,"style":118},[39,290],{"x":234,"y":132,"width":235,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,292,293],{"x":238,"y":135,"style":118},"950.0",[39,295],{"x":217,"y":154,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,297,158],{"x":243,"y":157,"style":64},[39,299],{"x":220,"y":154,"width":221,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,301,267],{"x":224,"y":157,"style":118},[39,303],{"x":227,"y":154,"width":228,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,305,168],{"x":231,"y":157,"style":118},[39,307],{"x":234,"y":154,"width":235,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,309,310],{"x":238,"y":157,"style":118},"300.0",[39,312],{"x":217,"y":176,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,314,180],{"x":243,"y":179,"style":64},[39,316],{"x":220,"y":176,"width":221,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,318,319],{"x":224,"y":179,"style":118},"East",[39,321],{"x":227,"y":176,"width":228,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,323,124],{"x":231,"y":179,"style":118},[39,325],{"x":234,"y":176,"width":235,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,327,328],{"x":238,"y":179,"style":118},"null",[39,330],{"x":217,"y":197,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,332,201],{"x":243,"y":200,"style":64},[39,334],{"x":220,"y":197,"width":221,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,336,141],{"x":224,"y":200,"style":118},[39,338],{"x":227,"y":197,"width":228,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,340,168],{"x":231,"y":200,"style":118},[39,342],{"x":234,"y":197,"width":235,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,344,345],{"x":238,"y":200,"style":118},"1050.0",[60,347,350],{"x":176,"y":348,"style":349},"29.0","font-size:12.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","before",[60,352,354],{"x":353,"y":348,"style":349},"592.4","after",[356,357],"line",{"x1":358,"y1":359,"x2":360,"y2":359,"stroke":361,"style":362},"315.9","136.0","456.9","var(--brand,#5b5cf0)","stroke-width:2px",[364,365],"polygon",{"points":366,"fill":367},"460.9,136.0 451.9,141.0 451.9,131.0","#5b5cf0",[39,369],{"x":370,"y":371,"width":372,"height":373,"rx":374,"fill":45,"stroke":53,"style":375},"338.4","103.0","100.0","22.0","11","stroke-width:1.2px",[60,377,381],{"x":378,"y":379,"style":380},"388.4","118.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","expressions",[383,384,386],"h2",{"id":385},"prerequisites","Prerequisites",[388,389,394],"pre",{"className":390,"code":391,"language":392,"meta":393,"style":393},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install polars fastexcel xlsxwriter pandas openpyxl\n","bash","",[395,396,397],"code",{"__ignoreMap":393},[398,399,401,405,409,412,415,418,421],"span",{"class":356,"line":400},1,[398,402,404],{"class":403},"sMTad","pip",[398,406,408],{"class":407},"srMev"," install",[398,410,411],{"class":407}," polars",[398,413,414],{"class":407}," fastexcel",[398,416,417],{"class":407}," xlsxwriter",[398,419,420],{"class":407}," pandas",[398,422,423],{"class":407}," openpyxl\n",[10,425,426],{},"The sample export:",[388,428,432],{"className":429,"code":430,"language":431,"meta":393,"style":393},"language-python shiki shiki-themes github-light github-dark-high-contrast","import datetime as dt\n\nimport pandas as pd\nimport polars as pl\n\npd.DataFrame({\n    \"Region\": [\" north\", \"South\", \"NORTH \", \"east\", \"South\", \"north\"],\n    \"Product\": [\"Tea\", \"tea\", \"Coffee\", \"Tea\", \"Coffee\", \"Coffee\"],\n    \"Revenue\": [\"1,200\", \"950\", \"€ 300\", \"n\u002Fa\", \"1 050\", \"700\"],\n    \"Units\": [12, 10, 3, None, 11, 7],\n    \"Date\": [dt.date(2026, 1, 5), dt.date(2026, 1, 9), dt.date(2026, 2, 2),\n             dt.date(2026, 2, 3), dt.date(2026, 2, 20), dt.date(2026, 3, 1)],\n}).to_excel(\"sales.xlsx\", index=False)\n\nraw = pl.read_excel(\"sales.xlsx\", schema_overrides={\"Revenue\": pl.String})\nprint(raw.schema)\n","python",[395,433,434,450,457,470,483,488,494,534,569,607,644,693,737,761,766,795],{"__ignoreMap":393},[398,435,436,440,444,447],{"class":356,"line":400},[398,437,439],{"class":438},"s-kum","import",[398,441,443],{"class":442},"skGVy"," datetime ",[398,445,446],{"class":438},"as",[398,448,449],{"class":442}," dt\n",[398,451,453],{"class":356,"line":452},2,[398,454,456],{"emptyLinePlaceholder":455},true,"\n",[398,458,460,462,465,467],{"class":356,"line":459},3,[398,461,439],{"class":438},[398,463,464],{"class":442}," pandas ",[398,466,446],{"class":438},[398,468,469],{"class":442}," pd\n",[398,471,473,475,478,480],{"class":356,"line":472},4,[398,474,439],{"class":438},[398,476,477],{"class":442}," polars ",[398,479,446],{"class":438},[398,481,482],{"class":442}," pl\n",[398,484,486],{"class":356,"line":485},5,[398,487,456],{"emptyLinePlaceholder":455},[398,489,491],{"class":356,"line":490},6,[398,492,493],{"class":442},"pd.DataFrame({\n",[398,495,497,500,503,506,509,512,514,517,519,522,524,526,528,531],{"class":356,"line":496},7,[398,498,499],{"class":407},"    \"Region\"",[398,501,502],{"class":442},": [",[398,504,505],{"class":407},"\" north\"",[398,507,508],{"class":442},", ",[398,510,511],{"class":407},"\"South\"",[398,513,508],{"class":442},[398,515,516],{"class":407},"\"NORTH \"",[398,518,508],{"class":442},[398,520,521],{"class":407},"\"east\"",[398,523,508],{"class":442},[398,525,511],{"class":407},[398,527,508],{"class":442},[398,529,530],{"class":407},"\"north\"",[398,532,533],{"class":442},"],\n",[398,535,537,540,542,545,547,550,552,555,557,559,561,563,565,567],{"class":356,"line":536},8,[398,538,539],{"class":407},"    \"Product\"",[398,541,502],{"class":442},[398,543,544],{"class":407},"\"Tea\"",[398,546,508],{"class":442},[398,548,549],{"class":407},"\"tea\"",[398,551,508],{"class":442},[398,553,554],{"class":407},"\"Coffee\"",[398,556,508],{"class":442},[398,558,544],{"class":407},[398,560,508],{"class":442},[398,562,554],{"class":407},[398,564,508],{"class":442},[398,566,554],{"class":407},[398,568,533],{"class":442},[398,570,572,575,577,580,582,585,587,590,592,595,597,600,602,605],{"class":356,"line":571},9,[398,573,574],{"class":407},"    \"Revenue\"",[398,576,502],{"class":442},[398,578,579],{"class":407},"\"1,200\"",[398,581,508],{"class":442},[398,583,584],{"class":407},"\"950\"",[398,586,508],{"class":442},[398,588,589],{"class":407},"\"€ 300\"",[398,591,508],{"class":442},[398,593,594],{"class":407},"\"n\u002Fa\"",[398,596,508],{"class":442},[398,598,599],{"class":407},"\"1 050\"",[398,601,508],{"class":442},[398,603,604],{"class":407},"\"700\"",[398,606,533],{"class":442},[398,608,610,613,615,619,621,624,626,628,630,633,635,637,639,642],{"class":356,"line":609},10,[398,611,612],{"class":407},"    \"Units\"",[398,614,502],{"class":442},[398,616,618],{"class":617},"sP0c6","12",[398,620,508],{"class":442},[398,622,623],{"class":617},"10",[398,625,508],{"class":442},[398,627,136],{"class":617},[398,629,508],{"class":442},[398,631,632],{"class":617},"None",[398,634,508],{"class":442},[398,636,374],{"class":617},[398,638,508],{"class":442},[398,640,641],{"class":617},"7",[398,643,533],{"class":442},[398,645,647,650,653,656,658,660,662,664,667,669,671,673,675,678,680,682,684,686,688,690],{"class":356,"line":646},11,[398,648,649],{"class":407},"    \"Date\"",[398,651,652],{"class":442},": [dt.date(",[398,654,655],{"class":617},"2026",[398,657,508],{"class":442},[398,659,90],{"class":617},[398,661,508],{"class":442},[398,663,180],{"class":617},[398,665,666],{"class":442},"), dt.date(",[398,668,655],{"class":617},[398,670,508],{"class":442},[398,672,90],{"class":617},[398,674,508],{"class":442},[398,676,677],{"class":617},"9",[398,679,666],{"class":442},[398,681,655],{"class":617},[398,683,508],{"class":442},[398,685,113],{"class":617},[398,687,508],{"class":442},[398,689,113],{"class":617},[398,691,692],{"class":442},"),\n",[398,694,696,699,701,703,705,707,709,711,713,715,717,719,722,724,726,728,730,732,734],{"class":356,"line":695},12,[398,697,698],{"class":442},"             dt.date(",[398,700,655],{"class":617},[398,702,508],{"class":442},[398,704,113],{"class":617},[398,706,508],{"class":442},[398,708,136],{"class":617},[398,710,666],{"class":442},[398,712,655],{"class":617},[398,714,508],{"class":442},[398,716,113],{"class":617},[398,718,508],{"class":442},[398,720,721],{"class":617},"20",[398,723,666],{"class":442},[398,725,655],{"class":617},[398,727,508],{"class":442},[398,729,136],{"class":617},[398,731,508],{"class":442},[398,733,90],{"class":617},[398,735,736],{"class":442},")],\n",[398,738,740,743,746,748,752,755,758],{"class":356,"line":739},13,[398,741,742],{"class":442},"}).to_excel(",[398,744,745],{"class":407},"\"sales.xlsx\"",[398,747,508],{"class":442},[398,749,751],{"class":750},"sa561","index",[398,753,754],{"class":438},"=",[398,756,757],{"class":617},"False",[398,759,760],{"class":442},")\n",[398,762,764],{"class":356,"line":763},14,[398,765,456],{"emptyLinePlaceholder":455},[398,767,769,772,774,777,779,781,784,786,789,792],{"class":356,"line":768},15,[398,770,771],{"class":442},"raw ",[398,773,754],{"class":438},[398,775,776],{"class":442}," pl.read_excel(",[398,778,745],{"class":407},[398,780,508],{"class":442},[398,782,783],{"class":750},"schema_overrides",[398,785,754],{"class":438},[398,787,788],{"class":442},"{",[398,790,791],{"class":407},"\"Revenue\"",[398,793,794],{"class":442},": pl.String})\n",[398,796,798,801],{"class":356,"line":797},16,[398,799,800],{"class":617},"print",[398,802,803],{"class":442},"(raw.schema)\n",[10,805,806,807,809],{},"Reading ",[395,808,106],{}," as a string is deliberate. Left to inference, a column of mixed text and numbers could come back with some values already lost; as text, every value arrives exactly as typed and the cleaning rules decide what it means.",[383,811,813],{"id":812},"step-1-write-the-cleaning-rules-as-expressions","Step 1 — Write the cleaning rules as expressions",[10,815,816],{},"Each rule is an expression: a description of a computation on a column, not yet applied to any data. Keeping them in a dictionary makes them reusable and easy to review:",[388,818,820],{"className":429,"code":819,"language":431,"meta":393,"style":393},"AMOUNT = pl.col(\"Revenue\").str.replace_all(r\"[^\\d.\\-]\", \"\").cast(pl.Float64, strict=False)\n\nRULES = {\n    \"region\": pl.col(\"Region\").str.strip_chars().str.to_titlecase(),\n    \"product\": pl.col(\"Product\").str.strip_chars().str.to_titlecase(),\n    \"revenue\": AMOUNT,\n    \"units\": pl.col(\"Units\").cast(pl.Int64),\n    \"month\": pl.col(\"Date\").dt.truncate(\"1mo\"),\n}\nclean = raw.select(**RULES)\nprint(clean)\n",[395,821,822,883,887,897,911,923,936,949,967,972,989],{"__ignoreMap":393},[398,823,824,827,830,833,835,838,841,844,847,850,853,857,861,864,866,868,871,874,877,879,881],{"class":356,"line":400},[398,825,826],{"class":617},"AMOUNT",[398,828,829],{"class":438}," =",[398,831,832],{"class":442}," pl.col(",[398,834,791],{"class":407},[398,836,837],{"class":442},").str.replace_all(",[398,839,840],{"class":438},"r",[398,842,843],{"class":407},"\"",[398,845,846],{"class":617},"[",[398,848,849],{"class":438},"^",[398,851,852],{"class":617},"\\d",[398,854,856],{"class":855},"sSjpA",".",[398,858,860],{"class":859},"s_b0D","\\-",[398,862,863],{"class":617},"]",[398,865,843],{"class":407},[398,867,508],{"class":442},[398,869,870],{"class":407},"\"\"",[398,872,873],{"class":442},").cast(pl.Float64, ",[398,875,876],{"class":750},"strict",[398,878,754],{"class":438},[398,880,757],{"class":617},[398,882,760],{"class":442},[398,884,885],{"class":356,"line":452},[398,886,456],{"emptyLinePlaceholder":455},[398,888,889,892,894],{"class":356,"line":459},[398,890,891],{"class":617},"RULES",[398,893,829],{"class":438},[398,895,896],{"class":442}," {\n",[398,898,899,902,905,908],{"class":356,"line":472},[398,900,901],{"class":407},"    \"region\"",[398,903,904],{"class":442},": pl.col(",[398,906,907],{"class":407},"\"Region\"",[398,909,910],{"class":442},").str.strip_chars().str.to_titlecase(),\n",[398,912,913,916,918,921],{"class":356,"line":485},[398,914,915],{"class":407},"    \"product\"",[398,917,904],{"class":442},[398,919,920],{"class":407},"\"Product\"",[398,922,910],{"class":442},[398,924,925,928,931,933],{"class":356,"line":490},[398,926,927],{"class":407},"    \"revenue\"",[398,929,930],{"class":442},": ",[398,932,826],{"class":617},[398,934,935],{"class":442},",\n",[398,937,938,941,943,946],{"class":356,"line":496},[398,939,940],{"class":407},"    \"units\"",[398,942,904],{"class":442},[398,944,945],{"class":407},"\"Units\"",[398,947,948],{"class":442},").cast(pl.Int64),\n",[398,950,951,954,956,959,962,965],{"class":356,"line":536},[398,952,953],{"class":407},"    \"month\"",[398,955,904],{"class":442},[398,957,958],{"class":407},"\"Date\"",[398,960,961],{"class":442},").dt.truncate(",[398,963,964],{"class":407},"\"1mo\"",[398,966,692],{"class":442},[398,968,969],{"class":356,"line":571},[398,970,971],{"class":442},"}\n",[398,973,974,977,979,982,985,987],{"class":356,"line":609},[398,975,976],{"class":442},"clean ",[398,978,754],{"class":438},[398,980,981],{"class":442}," raw.select(",[398,983,984],{"class":438},"**",[398,986,891],{"class":617},[398,988,760],{"class":442},[398,990,991,993],{"class":356,"line":646},[398,992,800],{"class":617},[398,994,995],{"class":442},"(clean)\n",[10,997,998,1001,1002,1005,1006,1009,1010,1013],{},[395,999,1000],{},"strip_chars"," and ",[395,1003,1004],{},"to_titlecase"," turn all three spellings of north into \"North\". The amount rule deletes every character that is not a digit, a point or a minus sign — thousands separators, currency symbols, spaces — and casts the rest. ",[395,1007,1008],{},"strict=False"," makes values that still do not parse, like \"n\u002Fa\", become null instead of raising. ",[395,1011,1012],{},"dt.truncate(\"1mo\")"," maps each date to the first of its month, a clean key for monthly totals. The rule assumes a decimal point; for exports that use a decimal comma, replace the comma with a point first.",[383,1015,1017],{"id":1016},"step-2-list-the-values-that-failed-to-parse","Step 2 — List the values that failed to parse",[10,1019,1020],{},"A lenient cast is only safe if you look at what it discarded. Filter the raw rows where the original had a value but the parsed amount is null:",[388,1022,1024],{"className":429,"code":1023,"language":431,"meta":393,"style":393},"failed = raw.filter(pl.col(\"Revenue\").is_not_null() & AMOUNT.is_null())\nprint(failed.select(\"Region\", \"Revenue\").rows())      # [('east', 'n\u002Fa')]\nprint(clean.null_count().row(0, named=True))\n# {'region': 0, 'product': 0, 'revenue': 1, 'units': 1, 'month': 0}\n",[395,1025,1026,1050,1070,1092],{"__ignoreMap":393},[398,1027,1028,1031,1033,1036,1038,1041,1044,1047],{"class":356,"line":400},[398,1029,1030],{"class":442},"failed ",[398,1032,754],{"class":438},[398,1034,1035],{"class":442}," raw.filter(pl.col(",[398,1037,791],{"class":407},[398,1039,1040],{"class":442},").is_not_null() ",[398,1042,1043],{"class":438},"&",[398,1045,1046],{"class":617}," AMOUNT",[398,1048,1049],{"class":442},".is_null())\n",[398,1051,1052,1054,1057,1059,1061,1063,1066],{"class":356,"line":452},[398,1053,800],{"class":617},[398,1055,1056],{"class":442},"(failed.select(",[398,1058,907],{"class":407},[398,1060,508],{"class":442},[398,1062,791],{"class":407},[398,1064,1065],{"class":442},").rows())      ",[398,1067,1069],{"class":1068},"s-wDw","# [('east', 'n\u002Fa')]\n",[398,1071,1072,1074,1077,1079,1081,1084,1086,1089],{"class":356,"line":459},[398,1073,800],{"class":617},[398,1075,1076],{"class":442},"(clean.null_count().row(",[398,1078,42],{"class":617},[398,1080,508],{"class":442},[398,1082,1083],{"class":750},"named",[398,1085,754],{"class":438},[398,1087,1088],{"class":617},"True",[398,1090,1091],{"class":442},"))\n",[398,1093,1094],{"class":356,"line":472},[398,1095,1096],{"class":1068},"# {'region': 0, 'product': 0, 'revenue': 1, 'units': 1, 'month': 0}\n",[10,1098,1099,1100,1102,1103,856],{},"Reusing the same ",[395,1101,826],{}," expression guarantees the check and the cleaning agree. \"n\u002Fa\" is a genuine placeholder. Note what the list cannot show: a revenue typed as \"1.200,00\" in European format parses without complaint as 1.2, because deleting the comma leaves a valid number. Lenient parsing only catches values that fail; if exports may mix number formats, check each file's format — for example by testing for a comma followed by exactly two digits at the end — before applying the rule. Placeholder handling in general is covered in ",[14,1104,1106],{"href":1105},"\u002Fadvanced-data-transformation-and-cleaning\u002Fhandling-missing-data-in-excel-reports\u002Freplace-placeholder-text-with-nan-in-pandas\u002F","Replace Placeholder Text with NaN in pandas",[383,1108,1110],{"id":1109},"step-3-add-conditional-columns-with-whenthen","Step 3 — Add conditional columns with when\u002Fthen",[10,1112,1113,1114,1117],{},"Polars' ",[395,1115,1116],{},"when\u002Fthen\u002Fotherwise"," is the equivalent of nested IF formulas, evaluated for the whole column at once:",[388,1119,1121],{"className":429,"code":1120,"language":431,"meta":393,"style":393},"clean = clean.with_columns(\n    size=pl.when(pl.col(\"revenue\") >= 1000).then(pl.lit(\"large\"))\n          .when(pl.col(\"revenue\") >= 500).then(pl.lit(\"medium\"))\n          .otherwise(pl.lit(\"small\"))\n)\nprint(clean.select(\"revenue\", \"size\").rows()[:4])\n# [(1200.0, 'large'), (950.0, 'medium'), (300.0, 'small'), (None, 'small')]\n",[395,1122,1123,1132,1162,1183,1193,1197,1219],{"__ignoreMap":393},[398,1124,1125,1127,1129],{"class":356,"line":400},[398,1126,976],{"class":442},[398,1128,754],{"class":438},[398,1130,1131],{"class":442}," clean.with_columns(\n",[398,1133,1134,1137,1139,1142,1145,1148,1151,1154,1157,1160],{"class":356,"line":452},[398,1135,1136],{"class":750},"    size",[398,1138,754],{"class":438},[398,1140,1141],{"class":442},"pl.when(pl.col(",[398,1143,1144],{"class":407},"\"revenue\"",[398,1146,1147],{"class":442},") ",[398,1149,1150],{"class":438},">=",[398,1152,1153],{"class":617}," 1000",[398,1155,1156],{"class":442},").then(pl.lit(",[398,1158,1159],{"class":407},"\"large\"",[398,1161,1091],{"class":442},[398,1163,1164,1167,1169,1171,1173,1176,1178,1181],{"class":356,"line":459},[398,1165,1166],{"class":442},"          .when(pl.col(",[398,1168,1144],{"class":407},[398,1170,1147],{"class":442},[398,1172,1150],{"class":438},[398,1174,1175],{"class":617}," 500",[398,1177,1156],{"class":442},[398,1179,1180],{"class":407},"\"medium\"",[398,1182,1091],{"class":442},[398,1184,1185,1188,1191],{"class":356,"line":472},[398,1186,1187],{"class":442},"          .otherwise(pl.lit(",[398,1189,1190],{"class":407},"\"small\"",[398,1192,1091],{"class":442},[398,1194,1195],{"class":356,"line":485},[398,1196,760],{"class":442},[398,1198,1199,1201,1204,1206,1208,1211,1214,1216],{"class":356,"line":490},[398,1200,800],{"class":617},[398,1202,1203],{"class":442},"(clean.select(",[398,1205,1144],{"class":407},[398,1207,508],{"class":442},[398,1209,1210],{"class":407},"\"size\"",[398,1212,1213],{"class":442},").rows()[:",[398,1215,158],{"class":617},[398,1217,1218],{"class":442},"])\n",[398,1220,1221],{"class":356,"line":496},[398,1222,1223],{"class":1068},"# [(1200.0, 'large'), (950.0, 'medium'), (300.0, 'small'), (None, 'small')]\n",[10,1225,1226,1227,1230,1231,1234],{},"Note the last row: a null revenue falls through every condition and lands in ",[395,1228,1229],{},"otherwise",", so the unknown order is labelled \"small\". Add an explicit first branch — ",[395,1232,1233],{},"pl.when(pl.col(\"revenue\").is_null()).then(pl.lit(\"unknown\"))"," — whenever nulls are possible.",[20,1236,29,1242,29,1245,29,1248,29,1252,29,1259,29,1270,29,1276,29,1280,29,1285,29,1288,29,1293,29,1300,29,1306,29,1310,29,1314,29,1318,29,1321,29,1326,29,1333,29,1338,29,1342,29,1345,29,1349,29,1352,29,1355,29,1361,29,1365,29,1368,29,1371,29,1375,29,1378,29,1381,29,1387,29,1391],{"viewBox":1237,"role":23,"ariaLabelledBy":1238,"xmlns":27,"style":1241},"4 0 752 142",[1239,1240],"pc-pipeline-t","pc-pipeline-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,1243,1244],{"id":1239},"From raw export to summary workbook",[35,1246,1247],{"id":1240},"Read the sheet with revenue as text, apply the cleaning expressions, list the values that failed to parse, add conditional columns, aggregate with group_by and window shares, and write the summary with write_excel.",[39,1249],{"x":158,"y":42,"width":1250,"height":1251,"fill":45},"752","142",[39,1253],{"x":1254,"y":1255,"width":1256,"height":1257,"rx":618,"fill":1258,"stroke":361,"style":362},"20.0","16.0","115.2","110.5","#f0f4ff",[1260,1261,1263],"g",{"transform":1262},"translate(65.6,37.8) scale(1.000)",[1264,1265],"path",{"d":1266,"fill":1267,"stroke":1268,"style":1269},"M4 4h16v16H4z M4 9h16 M4 14h16 M10 4v16","none","var(--brand-strong,#4338ca)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[60,1271,1275],{"x":1272,"y":1273,"style":1274},"77.6","84.2","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Read as text",[60,1277,783],{"x":1272,"y":1278,"style":1279},"103.8","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle",[356,1281],{"x1":1282,"y1":1283,"x2":1284,"y2":1283,"stroke":361,"style":362},"140.2","71.2","162.2",[364,1286],{"points":1287,"fill":367},"166.2,71.2 157.2,76.2 157.2,66.2",[39,1289],{"x":1290,"y":1255,"width":1256,"height":1257,"rx":618,"fill":1291,"stroke":1292,"style":362},"171.2","#d9f4f1","var(--teal,#0f9488)",[1260,1294,1296],{"transform":1295},"translate(216.8,29.0) scale(1.000)",[1264,1297],{"d":1298,"fill":1267,"stroke":1299,"style":1269},"M3 5h18l-7 8v6l-4 2v-8z","var(--teal-ink,#0b6157)",[60,1301,1305],{"x":1302,"y":1303,"style":1304},"228.8","75.5","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Clean",[60,1307,1309],{"x":1302,"y":1308,"style":1279},"95.0","strip, case,",[60,1311,1313],{"x":1302,"y":1312,"style":1279},"112.5","parse",[356,1315],{"x1":1316,"y1":1283,"x2":1317,"y2":1283,"stroke":361,"style":362},"291.4","313.4",[364,1319],{"points":1320,"fill":367},"317.4,71.2 308.4,76.2 308.4,66.2",[39,1322],{"x":1323,"y":1255,"width":1256,"height":1257,"rx":618,"fill":1324,"stroke":1325,"style":362},"322.4","#fdefd8","var(--gold,#b4740a)",[1260,1327,1329],{"transform":1328},"translate(368.0,29.0) scale(1.000)",[1264,1330],{"d":1331,"fill":1267,"stroke":1332,"style":1269},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4","var(--gold-ink,#7a4e06)",[60,1334,1337],{"x":1335,"y":1303,"style":1336},"380.0","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Check",[60,1339,1341],{"x":1335,"y":1340,"style":1336},"93.0","failures",[60,1343,1344],{"x":1335,"y":1312,"style":1279},"parsed is null",[356,1346],{"x1":1347,"y1":1283,"x2":1348,"y2":1283,"stroke":361,"style":362},"442.6","464.6",[364,1350],{"points":1351,"fill":367},"468.6,71.2 459.6,76.2 459.6,66.2",[39,1353],{"x":1354,"y":1255,"width":1256,"height":1257,"rx":618,"fill":1258,"stroke":361,"style":362},"473.6",[1260,1356,1358],{"transform":1357},"translate(519.2,29.0) scale(1.000)",[1264,1359],{"d":1360,"fill":1267,"stroke":1268,"style":1269},"M4 20h16 M7 17v-5 M12 17V7 M17 17v-8",[60,1362,1364],{"x":1363,"y":1303,"style":1274},"531.2","Aggregate",[60,1366,1367],{"x":1363,"y":1308,"style":1279},"group_by, over,",[60,1369,1370],{"x":1363,"y":1312,"style":1279},"pivot",[356,1372],{"x1":1373,"y1":1283,"x2":1374,"y2":1283,"stroke":361,"style":362},"593.8","615.8",[364,1376],{"points":1377,"fill":367},"619.8,71.2 610.8,76.2 610.8,66.2",[39,1379],{"x":1380,"y":1255,"width":1256,"height":1257,"rx":618,"fill":1258,"stroke":361,"style":362},"624.8",[1260,1382,1384],{"transform":1383},"translate(670.4,37.8) scale(1.000)",[1264,1385],{"d":1386,"fill":1267,"stroke":1268,"style":1269},"M6 3h9l4 4v14H6z M15 3v4h4 M9.5 11.5l4.5 6 M14 11.5l-4.5 6",[60,1388,1390],{"x":1389,"y":1273,"style":1274},"682.4","write_excel",[60,1392,1393],{"x":1389,"y":1278,"style":1279},"summary sheet",[383,1395,1397],{"id":1396},"step-4-aggregate-with-group_by","Step 4 — Aggregate with group_by",[10,1399,1400],{},"A group-by takes any number of aggregation expressions, each named with a keyword:",[388,1402,1404],{"className":429,"code":1403,"language":431,"meta":393,"style":393},"summary = clean.group_by(\"region\").agg(\n    revenue=pl.col(\"revenue\").sum(),\n    units=pl.col(\"units\").sum(),\n    orders=pl.len(),\n    avg_price=(pl.col(\"revenue\").sum() \u002F pl.col(\"units\").sum()).round(2),\n    products=pl.col(\"product\").n_unique(),\n    missing_revenue=pl.col(\"revenue\").is_null().sum(),\n).sort(\"revenue\", descending=True)\nprint(summary)\n",[395,1405,1406,1422,1437,1451,1461,1490,1505,1519,1537],{"__ignoreMap":393},[398,1407,1408,1411,1413,1416,1419],{"class":356,"line":400},[398,1409,1410],{"class":442},"summary ",[398,1412,754],{"class":438},[398,1414,1415],{"class":442}," clean.group_by(",[398,1417,1418],{"class":407},"\"region\"",[398,1420,1421],{"class":442},").agg(\n",[398,1423,1424,1427,1429,1432,1434],{"class":356,"line":452},[398,1425,1426],{"class":750},"    revenue",[398,1428,754],{"class":438},[398,1430,1431],{"class":442},"pl.col(",[398,1433,1144],{"class":407},[398,1435,1436],{"class":442},").sum(),\n",[398,1438,1439,1442,1444,1446,1449],{"class":356,"line":459},[398,1440,1441],{"class":750},"    units",[398,1443,754],{"class":438},[398,1445,1431],{"class":442},[398,1447,1448],{"class":407},"\"units\"",[398,1450,1436],{"class":442},[398,1452,1453,1456,1458],{"class":356,"line":472},[398,1454,1455],{"class":750},"    orders",[398,1457,754],{"class":438},[398,1459,1460],{"class":442},"pl.len(),\n",[398,1462,1463,1466,1468,1471,1473,1476,1479,1481,1483,1486,1488],{"class":356,"line":485},[398,1464,1465],{"class":750},"    avg_price",[398,1467,754],{"class":438},[398,1469,1470],{"class":442},"(pl.col(",[398,1472,1144],{"class":407},[398,1474,1475],{"class":442},").sum() ",[398,1477,1478],{"class":438},"\u002F",[398,1480,832],{"class":442},[398,1482,1448],{"class":407},[398,1484,1485],{"class":442},").sum()).round(",[398,1487,113],{"class":617},[398,1489,692],{"class":442},[398,1491,1492,1495,1497,1499,1502],{"class":356,"line":490},[398,1493,1494],{"class":750},"    products",[398,1496,754],{"class":438},[398,1498,1431],{"class":442},[398,1500,1501],{"class":407},"\"product\"",[398,1503,1504],{"class":442},").n_unique(),\n",[398,1506,1507,1510,1512,1514,1516],{"class":356,"line":496},[398,1508,1509],{"class":750},"    missing_revenue",[398,1511,754],{"class":438},[398,1513,1431],{"class":442},[398,1515,1144],{"class":407},[398,1517,1518],{"class":442},").is_null().sum(),\n",[398,1520,1521,1524,1526,1528,1531,1533,1535],{"class":356,"line":536},[398,1522,1523],{"class":442},").sort(",[398,1525,1144],{"class":407},[398,1527,508],{"class":442},[398,1529,1530],{"class":750},"descending",[398,1532,754],{"class":438},[398,1534,1088],{"class":617},[398,1536,760],{"class":442},[398,1538,1539,1541],{"class":356,"line":571},[398,1540,800],{"class":617},[398,1542,1543],{"class":442},"(summary)\n",[10,1545,1546,1549,1550,1553,1554,1557,1558,856],{},[395,1547,1548],{},"avg_price"," divides two sums, which gives the true price per unit rather than an average of per-order prices. The East row shows why ",[395,1551,1552],{},"missing_revenue"," belongs in the summary: its only order had no parseable revenue, and Polars' ",[395,1555,1556],{},"sum"," of nothing is 0 — so East reports revenue 0.0, which is not the same as zero sales. With the null count next to it, readers can tell the difference. Per-column aggregation rules are discussed in more depth in ",[14,1559,1561],{"href":1560},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcreating-pivot-tables-from-excel-data\u002Fuse-different-aggregations-per-column-in-a-pivot\u002F","Use Different Aggregations per Column in a pandas Pivot",[383,1563,1565],{"id":1564},"step-5-shares-with-over-and-a-monthly-pivot","Step 5 — Shares with over and a monthly pivot",[10,1567,1568],{},"A window expression computes a group value and broadcasts it back to each row — here, each order's share of its region's revenue:",[388,1570,1572],{"className":429,"code":1571,"language":431,"meta":393,"style":393},"shares = clean.with_columns(\n    share=(pl.col(\"revenue\") \u002F pl.col(\"revenue\").sum().over(\"region\")).round(3)\n)\nprint(shares.filter(pl.col(\"region\") == \"North\").select(\"product\", \"revenue\", \"share\").rows())\n# [('Tea', 1200.0, 0.545), ('Coffee', 300.0, 0.136), ('Coffee', 700.0, 0.318)]\n\nmonthly = clean.pivot(on=\"month\", index=\"region\", values=\"revenue\",\n                      aggregate_function=\"sum\").sort(\"region\")\nprint(monthly)\n",[395,1573,1574,1583,1614,1618,1652,1657,1661,1698,1714],{"__ignoreMap":393},[398,1575,1576,1579,1581],{"class":356,"line":400},[398,1577,1578],{"class":442},"shares ",[398,1580,754],{"class":438},[398,1582,1131],{"class":442},[398,1584,1585,1588,1590,1592,1594,1596,1598,1600,1602,1605,1607,1610,1612],{"class":356,"line":452},[398,1586,1587],{"class":750},"    share",[398,1589,754],{"class":438},[398,1591,1470],{"class":442},[398,1593,1144],{"class":407},[398,1595,1147],{"class":442},[398,1597,1478],{"class":438},[398,1599,832],{"class":442},[398,1601,1144],{"class":407},[398,1603,1604],{"class":442},").sum().over(",[398,1606,1418],{"class":407},[398,1608,1609],{"class":442},")).round(",[398,1611,136],{"class":617},[398,1613,760],{"class":442},[398,1615,1616],{"class":356,"line":459},[398,1617,760],{"class":442},[398,1619,1620,1622,1625,1627,1629,1632,1635,1638,1640,1642,1644,1646,1649],{"class":356,"line":472},[398,1621,800],{"class":617},[398,1623,1624],{"class":442},"(shares.filter(pl.col(",[398,1626,1418],{"class":407},[398,1628,1147],{"class":442},[398,1630,1631],{"class":438},"==",[398,1633,1634],{"class":407}," \"North\"",[398,1636,1637],{"class":442},").select(",[398,1639,1501],{"class":407},[398,1641,508],{"class":442},[398,1643,1144],{"class":407},[398,1645,508],{"class":442},[398,1647,1648],{"class":407},"\"share\"",[398,1650,1651],{"class":442},").rows())\n",[398,1653,1654],{"class":356,"line":485},[398,1655,1656],{"class":1068},"# [('Tea', 1200.0, 0.545), ('Coffee', 300.0, 0.136), ('Coffee', 700.0, 0.318)]\n",[398,1658,1659],{"class":356,"line":490},[398,1660,456],{"emptyLinePlaceholder":455},[398,1662,1663,1666,1668,1671,1674,1676,1679,1681,1683,1685,1687,1689,1692,1694,1696],{"class":356,"line":496},[398,1664,1665],{"class":442},"monthly ",[398,1667,754],{"class":438},[398,1669,1670],{"class":442}," clean.pivot(",[398,1672,1673],{"class":750},"on",[398,1675,754],{"class":438},[398,1677,1678],{"class":407},"\"month\"",[398,1680,508],{"class":442},[398,1682,751],{"class":750},[398,1684,754],{"class":438},[398,1686,1418],{"class":407},[398,1688,508],{"class":442},[398,1690,1691],{"class":750},"values",[398,1693,754],{"class":438},[398,1695,1144],{"class":407},[398,1697,935],{"class":442},[398,1699,1700,1703,1705,1708,1710,1712],{"class":356,"line":536},[398,1701,1702],{"class":750},"                      aggregate_function",[398,1704,754],{"class":438},[398,1706,1707],{"class":407},"\"sum\"",[398,1709,1523],{"class":442},[398,1711,1418],{"class":407},[398,1713,760],{"class":442},[398,1715,1716,1718],{"class":356,"line":571},[398,1717,800],{"class":617},[398,1719,1720],{"class":442},"(monthly)\n",[10,1722,1723,1726,1727,1730],{},[395,1724,1725],{},"over"," is Polars' equivalent of a SQL window function or pandas' ",[395,1728,1729],{},"groupby().transform()",", and it needs no join. The pivot puts months across the top for a report layout; the month columns are named from the dates, so rename them to \"Jan 2026\" and so on before writing if the audience prefers. In this version of Polars, region-month combinations with no orders show 0.0 in the pivot rather than null — another place where a count alongside the sum keeps the report honest.",[20,1732,29,1737,29,1740,29,1743,29,1746,29,1751,29,1758,29,1763,29,1768,29,1773,29,1780,29,1784,29,1789,29,1793,29,1798,29,1801,29,1807,29,1812,29,1816,29,1820,29,1825,29,1828,29,1833,29,1836],{"viewBox":1733,"role":23,"ariaLabelledBy":1734,"xmlns":27,"style":1241},"4 0 752 207",[1735,1736],"pc-over-t","pc-over-d",[31,1738,1739],{"id":1735},"group_by versus over",[35,1741,1742],{"id":1736},"group_by with agg returns one row per region, suited to a summary table. An expression with over returns one value per original row, the region's total broadcast to each order, suited to shares and rankings next to the detail rows.",[39,1744],{"x":158,"y":42,"width":1250,"height":1745,"fill":45},"207",[39,1747],{"x":1254,"y":1255,"width":1748,"height":1749,"rx":1750,"fill":1258,"stroke":361,"style":362},"351.0","175.0","14",[1260,1752,1754],{"transform":1753},"translate(182.5,29.0) scale(1.083)",[1264,1755],{"d":1756,"fill":1267,"stroke":1268,"style":1757},"M3 5h18v14H3z M3 10h18 M3 15h18 M9 5v14","stroke-width:1.66px;stroke-linecap:round;stroke-linejoin:round",[60,1759,1762],{"x":1760,"y":57,"style":1761},"195.5","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","group_by().agg()",[356,1764],{"x1":1765,"y1":1766,"x2":1767,"y2":1766,"stroke":361,"style":54},"36.0","91.0","355.0",[60,1769,1772],{"x":1770,"y":112,"style":1771},"60.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start","one row per group",[1260,1774,1776],{"transform":1775},"translate(38.5,99.5) scale(0.625)",[1264,1777],{"d":1778,"fill":1267,"stroke":1292,"style":1779},"M5 12.5l4.5 4.5L19 7","stroke-width:2.88px;stroke-linecap:round;stroke-linejoin:round",[60,1781,1783],{"x":1770,"y":1782,"style":1771},"137.0","summary tables",[1260,1785,1787],{"transform":1786},"translate(38.5,125.5) scale(0.625)",[1264,1788],{"d":1778,"fill":1267,"stroke":1292,"style":1779},[60,1790,1792],{"x":1770,"y":1791,"style":1771},"163.0","detail rows are gone",[1260,1794,1796],{"transform":1795},"translate(38.5,151.5) scale(0.625)",[1264,1797],{"d":1331,"fill":1267,"stroke":1325,"style":1779},[39,1799],{"x":1800,"y":1255,"width":1748,"height":1749,"rx":1750,"fill":1291,"stroke":1292,"style":362},"389.0",[1260,1802,1804],{"transform":1803},"translate(551.5,29.0) scale(1.083)",[1264,1805],{"d":1806,"fill":1267,"stroke":1299,"style":1757},"M12 3l9 5-9 5-9-5z M3 13l9 5 9-5 M3 17l9 5 9-5",[60,1808,1811],{"x":1809,"y":57,"style":1810},"564.5","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","expr.over(group)",[356,1813],{"x1":1814,"y1":1766,"x2":1815,"y2":1766,"stroke":1292,"style":54},"405.0","724.0",[60,1817,1819],{"x":1818,"y":112,"style":1771},"429.0","one value per original row",[1260,1821,1823],{"transform":1822},"translate(407.5,99.5) scale(0.625)",[1264,1824],{"d":1778,"fill":1267,"stroke":1292,"style":1779},[60,1826,1827],{"x":1818,"y":1782,"style":1771},"shares, ranks, running totals",[1260,1829,1831],{"transform":1830},"translate(407.5,125.5) scale(0.625)",[1264,1832],{"d":1778,"fill":1267,"stroke":1292,"style":1779},[60,1834,1835],{"x":1818,"y":1791,"style":1771},"no join back needed",[1260,1837,1839],{"transform":1838},"translate(407.5,151.5) scale(0.625)",[1264,1840],{"d":1778,"fill":1267,"stroke":1292,"style":1779},[383,1842,1844],{"id":1843},"step-6-run-the-pipeline-lazily","Step 6 — Run the pipeline lazily",[10,1846,1847,1850,1851,1854],{},[395,1848,1849],{},"read_excel"," is eager, but everything after it can be lazy. Calling ",[395,1852,1853],{},".lazy()"," lets Polars see the whole pipeline and optimise it — pushing filters down, dropping unused columns — before any work is done:",[388,1856,1858],{"className":429,"code":1857,"language":431,"meta":393,"style":393},"report = (\n    pl.read_excel(\"sales.xlsx\", schema_overrides={\"Revenue\": pl.String})\n    .lazy()\n    .select(**RULES)\n    .filter(pl.col(\"units\") > 5)\n    .group_by(\"product\")\n    .agg(units=pl.col(\"units\").sum(), revenue=pl.col(\"revenue\").sum())\n    .sort(\"product\")\n    .collect()\n)\nprint(report.rows())      # [('Coffee', 18, 1750.0), ('Tea', 22, 2150.0)]\n",[395,1859,1860,1870,1889,1894,1905,1922,1931,1959,1968,1973,1977],{"__ignoreMap":393},[398,1861,1862,1865,1867],{"class":356,"line":400},[398,1863,1864],{"class":442},"report ",[398,1866,754],{"class":438},[398,1868,1869],{"class":442}," (\n",[398,1871,1872,1875,1877,1879,1881,1883,1885,1887],{"class":356,"line":452},[398,1873,1874],{"class":442},"    pl.read_excel(",[398,1876,745],{"class":407},[398,1878,508],{"class":442},[398,1880,783],{"class":750},[398,1882,754],{"class":438},[398,1884,788],{"class":442},[398,1886,791],{"class":407},[398,1888,794],{"class":442},[398,1890,1891],{"class":356,"line":459},[398,1892,1893],{"class":442},"    .lazy()\n",[398,1895,1896,1899,1901,1903],{"class":356,"line":472},[398,1897,1898],{"class":442},"    .select(",[398,1900,984],{"class":438},[398,1902,891],{"class":617},[398,1904,760],{"class":442},[398,1906,1907,1910,1912,1914,1917,1920],{"class":356,"line":485},[398,1908,1909],{"class":442},"    .filter(pl.col(",[398,1911,1448],{"class":407},[398,1913,1147],{"class":442},[398,1915,1916],{"class":438},">",[398,1918,1919],{"class":617}," 5",[398,1921,760],{"class":442},[398,1923,1924,1927,1929],{"class":356,"line":490},[398,1925,1926],{"class":442},"    .group_by(",[398,1928,1501],{"class":407},[398,1930,760],{"class":442},[398,1932,1933,1936,1939,1941,1943,1945,1948,1950,1952,1954,1956],{"class":356,"line":496},[398,1934,1935],{"class":442},"    .agg(",[398,1937,1938],{"class":750},"units",[398,1940,754],{"class":438},[398,1942,1431],{"class":442},[398,1944,1448],{"class":407},[398,1946,1947],{"class":442},").sum(), ",[398,1949,258],{"class":750},[398,1951,754],{"class":438},[398,1953,1431],{"class":442},[398,1955,1144],{"class":407},[398,1957,1958],{"class":442},").sum())\n",[398,1960,1961,1964,1966],{"class":356,"line":536},[398,1962,1963],{"class":442},"    .sort(",[398,1965,1501],{"class":407},[398,1967,760],{"class":442},[398,1969,1970],{"class":356,"line":571},[398,1971,1972],{"class":442},"    .collect()\n",[398,1974,1975],{"class":356,"line":609},[398,1976,760],{"class":442},[398,1978,1979,1981,1984],{"class":356,"line":646},[398,1980,800],{"class":617},[398,1982,1983],{"class":442},"(report.rows())      ",[398,1985,1986],{"class":1068},"# [('Coffee', 18, 1750.0), ('Tea', 22, 2150.0)]\n",[10,1988,1989,1990,1992,1993,1996,1997,1999],{},"Because ",[395,1991,891],{}," is a dictionary of expressions, the same cleaning runs unchanged in eager and lazy code. On a sheet this small the difference is invisible; on hundreds of thousands of rows, letting the optimiser drop the unused ",[395,1994,1995],{},"month"," column and apply the filter early saves real time and memory. Grouping on the cleaned ",[395,1998,253],{}," column matters: grouping the raw column would give \"Tea\" and \"tea\" as two products.",[383,2001,2003],{"id":2002},"step-7-write-the-summary-to-excel","Step 7 — Write the summary to Excel",[10,2005,2006,2007,2009],{},"Polars writes workbooks through XlsxWriter with ",[395,2008,1390],{},", which can size columns and add a table style in the same call:",[388,2011,2013],{"className":429,"code":2012,"language":431,"meta":393,"style":393},"summary.write_excel(\"summary.xlsx\", worksheet=\"Summary\", autofit=True,\n                    table_style=\"Table Style Medium 2\")\nprint(pd.read_excel(\"summary.xlsx\", sheet_name=\"Summary\").columns.tolist())\n",[395,2014,2015,2044,2056],{"__ignoreMap":393},[398,2016,2017,2020,2023,2025,2028,2030,2033,2035,2038,2040,2042],{"class":356,"line":400},[398,2018,2019],{"class":442},"summary.write_excel(",[398,2021,2022],{"class":407},"\"summary.xlsx\"",[398,2024,508],{"class":442},[398,2026,2027],{"class":750},"worksheet",[398,2029,754],{"class":438},[398,2031,2032],{"class":407},"\"Summary\"",[398,2034,508],{"class":442},[398,2036,2037],{"class":750},"autofit",[398,2039,754],{"class":438},[398,2041,1088],{"class":617},[398,2043,935],{"class":442},[398,2045,2046,2049,2051,2054],{"class":356,"line":452},[398,2047,2048],{"class":750},"                    table_style",[398,2050,754],{"class":438},[398,2052,2053],{"class":407},"\"Table Style Medium 2\"",[398,2055,760],{"class":442},[398,2057,2058,2060,2063,2065,2067,2070,2072,2074],{"class":356,"line":459},[398,2059,800],{"class":617},[398,2061,2062],{"class":442},"(pd.read_excel(",[398,2064,2022],{"class":407},[398,2066,508],{"class":442},[398,2068,2069],{"class":750},"sheet_name",[398,2071,754],{"class":438},[398,2073,2032],{"class":407},[398,2075,2076],{"class":442},").columns.tolist())\n",[10,2078,2079,2080,856],{},"Formatting options such as number formats per column and conditional formats are covered in ",[14,2081,2083],{"href":2082},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fwrite-a-polars-dataframe-to-excel-with-formatting\u002F","Write a Polars DataFrame to Excel with Formatting",[383,2085,2087],{"id":2086},"common-pitfalls","Common pitfalls",[2089,2090,2091,2099,2112,2122],"ul",{},[2092,2093,2094,2098],"li",{},[2095,2096,2097],"strong",{},"Casting with strict=True on dirty text."," The default strict cast raises on the first bad value, with no list of the others. Cast leniently and report failures instead.",[2092,2100,2101,2104,2105,2107,2108,2111],{},[2095,2102,2103],{},"Title case on codes."," ",[395,2106,1004],{}," suits names, not codes: \"UK\" becomes \"Uk\" and \"SKU-a1\" becomes \"Sku-A1\". Use ",[395,2109,2110],{},"to_uppercase"," for codes and IDs.",[2092,2113,2114,2117,2118,2121],{},[2095,2115,2116],{},"Cleaning after grouping."," Normalise text before ",[395,2119,2120],{},"group_by",", or variants of the same name become separate groups.",[2092,2123,2124,2127],{},[2095,2125,2126],{},"Treating 0 as \"no data\"."," Sums of all-null groups are 0; count nulls alongside every total that can have gaps.",[383,2129,2131],{"id":2130},"conclusion","Conclusion",[10,2133,2134,2135,2138,2139,2141,2142,2144,2145,2147],{},"Polars expressions turn a cleaning specification into reusable values: trim and normalise text, strip formatting from amounts and cast leniently, then list what failed. Add conditional columns with ",[395,2136,2137],{},"when\u002Fthen",", aggregate with ",[395,2140,2120],{}," and named expressions, compute shares with ",[395,2143,1725],{},", pivot for layout, and run the whole thing lazily for large sheets before writing the summary with ",[395,2146,1390],{},". Keep null counts next to totals so an unknown never reads as zero.",[383,2149,2151],{"id":2150},"frequently-asked-questions","Frequently asked questions",[10,2153,2154,2157],{},[2095,2155,2156],{},"How do I convert a text column like \"1,200\" or \"€ 300\" to numbers in Polars?","\nRemove everything except digits, the decimal point and the minus sign with str.replace_all, then cast to Float64 with strict=False. Values that still cannot be parsed become null, so list them before continuing.",[10,2159,2160,2163],{},[2095,2161,2162],{},"Why is the sum of a group 0 when all its values are missing?","\nPolars' sum ignores nulls, and the sum of nothing is 0. Count the nulls in the same aggregation, or use a when\u002Fthen expression that returns null for groups without any values, so an unknown total is not reported as zero.",[10,2165,2166,2169],{},[2095,2167,2168],{},"How do I calculate each row's share of its group total?","\nDivide the column by the same column's sum computed over the group, pl.col(\"revenue\") \u002F pl.col(\"revenue\").sum().over(\"region\"). The over clause is the Polars equivalent of a SQL window function.",[10,2171,2172,2175],{},[2095,2173,2174],{},"Should I use lazy mode for Excel data?","\nread_excel is eager, but you can call .lazy() on the result and build the rest of the pipeline lazily. Polars then optimises the whole query, which pays off on large sheets with several filters and aggregations.",[383,2177,2179],{"id":2178},"related","Related",[2089,2181,2182,2188,2195,2202],{},[2092,2183,2184,2185,2187],{},"Up one level: ",[14,2186,17],{"href":16}," — fast Excel reading.",[2092,2189,2190,2194],{},[14,2191,2193],{"href":2192},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fread-multiple-excel-sheets-with-polars\u002F","Read Multiple Excel Sheets with Polars"," — building the input frame from many sheets.",[2092,2196,2197,2201],{},[14,2198,2200],{"href":2199},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fstrip-whitespace-and-normalise-text-columns-with-pandas\u002F","Strip Whitespace and Normalise Text Columns with pandas"," — the same text problems in pandas.",[2092,2203,2204,2208],{},[14,2205,2207],{"href":2206},"\u002Fgetting-started-with-python-excel-automation\u002Fchoosing-a-python-excel-library\u002Fpandas-vs-polars-for-excel-workflows\u002F","Pandas vs Polars for Excel Workflows"," — choosing between them.",[2210,2211,2212],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .s_b0D, html code.shiki .s_b0D{--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#72F088;--shiki-dark-font-weight:bold}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}",{"title":393,"searchDepth":452,"depth":452,"links":2214},[2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226],{"id":385,"depth":452,"text":386},{"id":812,"depth":452,"text":813},{"id":1016,"depth":452,"text":1017},{"id":1109,"depth":452,"text":1110},{"id":1396,"depth":452,"text":1397},{"id":1564,"depth":452,"text":1565},{"id":1843,"depth":452,"text":1844},{"id":2002,"depth":452,"text":2003},{"id":2086,"depth":452,"text":2087},{"id":2130,"depth":452,"text":2131},{"id":2150,"depth":452,"text":2151},{"id":2178,"depth":452,"text":2179},"2026-09-23","Clean a messy Excel export with Polars expressions — trim and normalise text, parse amounts typed with currency symbols and thousands separators, find the values that failed, add conditional columns, then aggregate with group_by, window shares and a pivot, and write the summary back to Excel.","md",[2231,2233,2235,2237],{"q":2156,"a":2232},"Remove everything except digits, the decimal point and the minus sign with str.replace_all, then cast to Float64 with strict=False. Values that still cannot be parsed become null, so list them before continuing.",{"q":2162,"a":2234},"Polars' sum ignores nulls, and the sum of nothing is 0. Count the nulls in the same aggregation, or use a when\u002Fthen expression that returns null for groups without any values, so an unknown total is not reported as zero.",{"q":2168,"a":2236},"Divide the column by the same column's sum computed over the group, pl.col(\"revenue\") \u002F pl.col(\"revenue\").sum().over(\"region\"). The over clause is the Polars equivalent of a SQL window function.",{"q":2174,"a":2238},"read_excel is eager, but you can call .lazy() on the result and build the rest of the pipeline lazily. Polars then optimises the whole query, which pays off on large sheets with several filters and aggregations.","clean and aggregate excel data with polars expressions",null,{"breadcrumb":2242},[2243,2245,2248],{"name":2244,"item":1478},"Home",{"name":2246,"item":2247},"Advanced Data Transformation and Cleaning for Excel Automation","\u002Fadvanced-data-transformation-and-cleaning\u002F",{"name":17,"item":16},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fclean-and-aggregate-excel-data-with-polars",{"title":5,"description":2251},"Clean Excel data with Polars — str.strip_chars and case, parsing text amounts with cast(strict=False), listing failed values, when\u002Fthen columns, group_by aggregations, shares with over(), pivot, lazy pipelines and write_excel.","clean-and-aggregate-excel-data-with-polars","advanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fclean-and-aggregate-excel-data-with-polars\u002Findex",[2255,2256,2257],"polars","data-cleaning","pivots-and-summaries","how-to","hFw3b3ITeyPdPUKN3KxtK3X1ANJiKtTa6B81DRcNRIY",[2261,2264],{"title":17,"path":2262,"stem":2263,"children":-1},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow","advanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Findex",{"title":2265,"path":2266,"stem":2267,"children":-1},"Clean Wide Excel Sheets with Polars Column Selectors","\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fclean-wide-excel-sheets-with-polars-column-selectors","advanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fclean-wide-excel-sheets-with-polars-column-selectors\u002Findex",[2269,2271],{"path":2270,"title":2246},"\u002Fadvanced-data-transformation-and-cleaning",{"path":2262,"title":17},[],[2274,2275,2278,2282,2285,2288],{"path":2266,"title":2265,"kind":2258},{"path":2276,"title":2277,"kind":2258},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fconvert-pandas-excel-code-to-polars","Convert pandas Excel Code to Polars",{"path":2279,"title":2280,"kind":2281},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Ffix-schema-and-type-errors-when-reading-excel-with-polars","Fix Schema and Type Errors When Reading Excel with Polars","fix",{"path":2283,"title":2284,"kind":2258},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fjoin-and-pivot-excel-data-with-polars","Join and Pivot Excel Data with Polars",{"path":2286,"title":2287,"kind":2258},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fread-an-excel-file-with-polars-read-excel","Read an Excel File with polars.read_excel",{"path":2289,"title":2193,"kind":2258},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fread-multiple-excel-sheets-with-polars",1790972098112]