[{"data":1,"prerenderedAt":2459},["ShallowReactive",2],{"doc:\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Ffilter-excel-rows-by-condition-with-pandas":3,"surround:\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Ffilter-excel-rows-by-condition-with-pandas":2425,"ancestors:\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Ffilter-excel-rows-by-condition-with-pandas":2434,"children:\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Ffilter-excel-rows-by-condition-with-pandas":2439,"related:\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Ffilter-excel-rows-by-condition-with-pandas":2440},{"id":4,"title":5,"body":6,"dateModified":2392,"datePublished":2392,"description":2393,"extension":2394,"faq":2395,"keyword":2404,"kind":2405,"meta":2406,"navigation":100,"path":2415,"seo":2416,"slug":2419,"stem":2420,"topics":2421,"type":2423,"__hash__":2424},"docs\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Ffilter-excel-rows-by-condition-with-pandas\u002Findex.md","Filter Excel Rows by Condition with pandas",{"type":7,"value":8,"toc":2378},"minimark",[9,33,38,66,72,167,171,178,280,295,559,563,577,799,823,827,841,978,1012,1160,1164,1177,1362,1399,1403,1416,1490,1504,1508,1511,1787,1798,1802,1809,2008,2176,2188,2192,2267,2271,2295,2299,2315,2321,2335,2341,2345,2374],[10,11,12,13,17,18,22,23,26,27,32],"p",{},"Filtering is the first thing most scripts do after reading a sheet: only this region, only open orders, only amounts over a threshold, only last month. Excel's AutoFilter does it by clicking; pandas does it with a ",[14,15,16],"em",{},"boolean mask"," — a column of True and False, one per row — and a handful of methods that build masks for common conditions. The syntax is short but has sharp edges: ",[19,20,21],"code",{},"and"," instead of ",[19,24,25],{},"&"," raises an error, a missing pair of brackets silently changes the meaning, and a blank cell can crash a text search. This page, part of ",[28,29,31],"a",{"href":30},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002F","Cleaning Excel Data with pandas",", covers the conditions you will actually write and ends with filtering a formatted workbook without losing its formatting.",[34,35,37],"h2",{"id":36},"prerequisites","Prerequisites",[39,40,45],"pre",{"className":41,"code":42,"language":43,"meta":44,"style":44},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas openpyxl\n","bash","",[19,46,47],{"__ignoreMap":44},[48,49,52,56,60,63],"span",{"class":50,"line":51},"line",1,[48,53,55],{"class":54},"sMTad","pip",[48,57,59],{"class":58},"srMev"," install",[48,61,62],{"class":58}," pandas",[48,64,65],{"class":58}," openpyxl\n",[10,67,68,71],{},[19,69,70],{},"orders.xlsx"," has 40 orders from August and September 2026 with a date, region, customer, status, amount and a free-text note. Two amounts are missing and some notes are blank — the gaps that make filters misbehave. The sheet has a styled header row, which matters in the last step.",[39,73,77],{"className":74,"code":75,"language":76,"meta":44,"style":44},"language-python shiki shiki-themes github-light github-dark-high-contrast","import pandas as pd\n\ndf = pd.read_excel(\"orders.xlsx\", sheet_name=\"Orders\")\nprint(df.shape)\nprint(df.head(3).to_string(index=False))\n","python",[19,78,79,95,102,132,142],{"__ignoreMap":44},[48,80,81,85,89,92],{"class":50,"line":51},[48,82,84],{"class":83},"s-kum","import",[48,86,88],{"class":87},"skGVy"," pandas ",[48,90,91],{"class":83},"as",[48,93,94],{"class":87}," pd\n",[48,96,98],{"class":50,"line":97},2,[48,99,101],{"emptyLinePlaceholder":100},true,"\n",[48,103,105,108,111,114,117,120,124,126,129],{"class":50,"line":104},3,[48,106,107],{"class":87},"df ",[48,109,110],{"class":83},"=",[48,112,113],{"class":87}," pd.read_excel(",[48,115,116],{"class":58},"\"orders.xlsx\"",[48,118,119],{"class":87},", ",[48,121,123],{"class":122},"sa561","sheet_name",[48,125,110],{"class":83},[48,127,128],{"class":58},"\"Orders\"",[48,130,131],{"class":87},")\n",[48,133,135,139],{"class":50,"line":134},4,[48,136,138],{"class":137},"sP0c6","print",[48,140,141],{"class":87},"(df.shape)\n",[48,143,145,147,150,153,156,159,161,164],{"class":50,"line":144},5,[48,146,138],{"class":137},[48,148,149],{"class":87},"(df.head(",[48,151,152],{"class":137},"3",[48,154,155],{"class":87},").to_string(",[48,157,158],{"class":122},"index",[48,160,110],{"class":83},[48,162,163],{"class":137},"False",[48,165,166],{"class":87},"))\n",[34,168,170],{"id":169},"step-1-one-condition-a-boolean-mask","Step 1 — One condition: a boolean mask",[10,172,173,174,177],{},"Comparing a column with a value gives a Series of True\u002FFalse. Put that mask inside ",[19,175,176],{},"df[...]"," to keep the rows where it is True:",[39,179,181],{"className":74,"code":180,"language":76,"meta":44,"style":44},"is_open = df[\"Status\"] == \"Open\"\nprint(is_open.head(5).tolist())\nopen_orders = df[is_open]\nbig = df[df[\"Amount\"] > 1000]\nprint(len(open_orders), \"open,\", len(big), \"over 1,000\")\n",[19,182,183,205,218,228,252],{"__ignoreMap":44},[48,184,185,188,190,193,196,199,202],{"class":50,"line":51},[48,186,187],{"class":87},"is_open ",[48,189,110],{"class":83},[48,191,192],{"class":87}," df[",[48,194,195],{"class":58},"\"Status\"",[48,197,198],{"class":87},"] ",[48,200,201],{"class":83},"==",[48,203,204],{"class":58}," \"Open\"\n",[48,206,207,209,212,215],{"class":50,"line":97},[48,208,138],{"class":137},[48,210,211],{"class":87},"(is_open.head(",[48,213,214],{"class":137},"5",[48,216,217],{"class":87},").tolist())\n",[48,219,220,223,225],{"class":50,"line":104},[48,221,222],{"class":87},"open_orders ",[48,224,110],{"class":83},[48,226,227],{"class":87}," df[is_open]\n",[48,229,230,233,235,238,241,243,246,249],{"class":50,"line":134},[48,231,232],{"class":87},"big ",[48,234,110],{"class":83},[48,236,237],{"class":87}," df[df[",[48,239,240],{"class":58},"\"Amount\"",[48,242,198],{"class":87},[48,244,245],{"class":83},">",[48,247,248],{"class":137}," 1000",[48,250,251],{"class":87},"]\n",[48,253,254,256,259,262,265,268,270,272,275,278],{"class":50,"line":144},[48,255,138],{"class":137},[48,257,258],{"class":87},"(",[48,260,261],{"class":137},"len",[48,263,264],{"class":87},"(open_orders), ",[48,266,267],{"class":58},"\"open,\"",[48,269,119],{"class":87},[48,271,261],{"class":137},[48,273,274],{"class":87},"(big), ",[48,276,277],{"class":58},"\"over 1,000\"",[48,279,131],{"class":87},[10,281,282,283,286,287,290,291,294],{},"Rows with a missing amount are not in ",[19,284,285],{},"big",": any comparison with ",[19,288,289],{},"NaN"," is False, so the two orders without an amount drop out of every numeric filter. That is usually right, but it means \"over 1,000\" plus \"1,000 or less\" does not add up to all rows — check ",[19,292,293],{},"df[\"Amount\"].isna().sum()"," when the counts matter.",[296,297,305,306,305,310,305,314,305,322,305,331,305,335,305,342,305,346,305,350,305,354,305,358,305,362,305,367,305,369,305,373,305,375,305,378,305,380,305,383,305,386,305,390,305,392,305,396,305,398,305,401,305,406,305,410,305,413,305,416,305,418,305,421,305,423,305,426,305,428,305,430,305,433,305,437,305,439,305,442,305,444,305,447,305,449,305,451,305,454,305,457,305,459,305,462,305,464,305,466,305,468,305,470,305,473,305,476,305,479,305,483,305,486,305,488,305,491,305,493,305,495,305,497,305,499,305,501,305,503,305,505,305,507,305,509,305,511,305,513,305,515,305,517,305,519,305,521,305,523,305,529,305,533,305,540,305,545,305,553],"svg",{"viewBox":298,"role":299,"ariaLabelledBy":300,"xmlns":303,"style":304},"100 0 560 220","img",[301,302],"fl-mask-t","fl-mask-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:560px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[307,308,309],"title",{"id":301},"A mask selects the rows where it is True",[311,312,313],"desc",{"id":302},"On the left five orders with a mask column of True and False values for Status equals Open. On the right only the two rows where the mask was True remain.",[315,316],"rect",{"x":317,"y":318,"width":319,"height":320,"fill":321},"100","0","560","220","#ffffff",[315,323],{"x":324,"y":325,"width":326,"height":327,"rx":318,"fill":328,"stroke":329,"style":330},"116.4","40.0","32.0","24.0","#e7ebef","var(--line,#cdd5e6)","stroke-width:1px",[315,332],{"x":333,"y":325,"width":334,"height":327,"rx":318,"fill":328,"stroke":329,"style":330},"148.4","68.1",[336,337,341],"text",{"x":338,"y":339,"style":340},"182.5","57.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[315,343],{"x":344,"y":325,"width":345,"height":327,"rx":318,"fill":328,"stroke":329,"style":330},"216.5","80.5",[336,347,349],{"x":348,"y":339,"style":340},"256.8","B",[315,351],{"x":352,"y":325,"width":353,"height":327,"rx":318,"fill":328,"stroke":329,"style":330},"297.0","54.4",[336,355,357],{"x":356,"y":339,"style":340},"324.3","C",[315,359],{"x":324,"y":360,"width":326,"height":361,"rx":318,"fill":328,"stroke":329,"style":330},"64.0","28.0",[336,363,366],{"x":364,"y":365,"style":340},"132.4","83.0","1",[315,368],{"x":333,"y":360,"width":334,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,370,372],{"x":338,"y":365,"style":371},"font-size:11px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","OrderID",[315,374],{"x":344,"y":360,"width":345,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,376,377],{"x":348,"y":365,"style":371},"Status",[315,379],{"x":352,"y":360,"width":353,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,381,382],{"x":356,"y":365,"style":371},"mask",[315,384],{"x":324,"y":385,"width":326,"height":361,"rx":318,"fill":328,"stroke":329,"style":330},"92.0",[336,387,389],{"x":364,"y":388,"style":340},"111.0","2",[315,391],{"x":333,"y":385,"width":334,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,393,395],{"x":338,"y":388,"style":394},"font-size:11px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","5001",[315,397],{"x":344,"y":385,"width":345,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,399,400],{"x":348,"y":388,"style":394},"Open",[315,402],{"x":352,"y":385,"width":353,"height":361,"rx":318,"fill":403,"stroke":404,"style":405},"#d9f4f1","var(--teal,#0f9488)","stroke-width:1.5px",[336,407,409],{"x":356,"y":388,"style":408},"font-size:11px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","True",[315,411],{"x":324,"y":412,"width":326,"height":361,"rx":318,"fill":328,"stroke":329,"style":330},"120.0",[336,414,152],{"x":364,"y":415,"style":340},"139.0",[315,417],{"x":333,"y":412,"width":334,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,419,420],{"x":338,"y":415,"style":394},"5002",[315,422],{"x":344,"y":412,"width":345,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,424,425],{"x":348,"y":415,"style":394},"Shipped",[315,427],{"x":352,"y":412,"width":353,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,429,163],{"x":356,"y":415,"style":394},[315,431],{"x":324,"y":432,"width":326,"height":361,"rx":318,"fill":328,"stroke":329,"style":330},"148.0",[336,434,436],{"x":364,"y":435,"style":340},"167.0","4",[315,438],{"x":333,"y":432,"width":334,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,440,441],{"x":338,"y":435,"style":394},"5003",[315,443],{"x":344,"y":432,"width":345,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,445,446],{"x":348,"y":435,"style":394},"Cancelled",[315,448],{"x":352,"y":432,"width":353,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,450,163],{"x":356,"y":435,"style":394},[315,452],{"x":324,"y":453,"width":326,"height":361,"rx":318,"fill":328,"stroke":329,"style":330},"176.0",[336,455,214],{"x":364,"y":456,"style":340},"195.0",[315,458],{"x":333,"y":453,"width":334,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,460,461],{"x":338,"y":456,"style":394},"5004",[315,463],{"x":344,"y":453,"width":345,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,465,400],{"x":348,"y":456,"style":394},[315,467],{"x":352,"y":453,"width":353,"height":361,"rx":318,"fill":403,"stroke":404,"style":405},[336,469,409],{"x":356,"y":456,"style":408},[315,471],{"x":472,"y":325,"width":326,"height":327,"rx":318,"fill":328,"stroke":329,"style":330},"483.1",[315,474],{"x":475,"y":325,"width":334,"height":327,"rx":318,"fill":328,"stroke":329,"style":330},"515.1",[336,477,341],{"x":478,"y":339,"style":340},"549.1",[315,480],{"x":481,"y":325,"width":482,"height":327,"rx":318,"fill":328,"stroke":329,"style":330},"583.2","60.4",[336,484,349],{"x":485,"y":339,"style":340},"613.4",[315,487],{"x":472,"y":360,"width":326,"height":361,"rx":318,"fill":328,"stroke":329,"style":330},[336,489,366],{"x":490,"y":365,"style":340},"499.1",[315,492],{"x":475,"y":360,"width":334,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,494,372],{"x":478,"y":365,"style":371},[315,496],{"x":481,"y":360,"width":482,"height":361,"rx":318,"fill":321,"stroke":329,"style":330},[336,498,377],{"x":485,"y":365,"style":371},[315,500],{"x":472,"y":385,"width":326,"height":361,"rx":318,"fill":328,"stroke":329,"style":330},[336,502,389],{"x":490,"y":388,"style":340},[315,504],{"x":475,"y":385,"width":334,"height":361,"rx":318,"fill":403,"stroke":404,"style":405},[336,506,395],{"x":478,"y":388,"style":408},[315,508],{"x":481,"y":385,"width":482,"height":361,"rx":318,"fill":403,"stroke":404,"style":405},[336,510,400],{"x":485,"y":388,"style":408},[315,512],{"x":472,"y":412,"width":326,"height":361,"rx":318,"fill":328,"stroke":329,"style":330},[336,514,152],{"x":490,"y":415,"style":340},[315,516],{"x":475,"y":412,"width":334,"height":361,"rx":318,"fill":403,"stroke":404,"style":405},[336,518,461],{"x":478,"y":415,"style":408},[315,520],{"x":481,"y":412,"width":482,"height":361,"rx":318,"fill":403,"stroke":404,"style":405},[336,522,400],{"x":485,"y":415,"style":408},[336,524,528],{"x":525,"y":526,"style":527},"234.0","29.0","font-size:12.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","before",[336,530,532],{"x":531,"y":526,"style":527},"563.3","after",[50,534],{"x1":535,"y1":536,"x2":537,"y2":536,"stroke":538,"style":539},"361.5","94.0","469.1","var(--brand,#5b5cf0)","stroke-width:2px",[541,542],"polygon",{"points":543,"fill":544},"473.1,94.0 464.1,99.0 464.1,89.0","#5b5cf0",[315,546],{"x":547,"y":548,"width":549,"height":550,"rx":551,"fill":321,"stroke":329,"style":552},"380.6","61.0","73.3","22.0","11","stroke-width:1.2px",[336,554,558],{"x":555,"y":556,"style":557},"417.3","76.0","font-size:11.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","df[mask]",[34,560,562],{"id":561},"step-2-several-conditions-and","Step 2 — Several conditions: &, | and ~",[10,564,565,566,568,569,572,573,576],{},"Combine masks with ",[19,567,25],{}," (and), ",[19,570,571],{},"|"," (or) and ",[19,574,575],{},"~"," (not). Each condition needs its own brackets:",[39,578,580],{"className":74,"code":579,"language":76,"meta":44,"style":44},"north_open_big = df[(df[\"Region\"] == \"North\") & (df[\"Status\"] == \"Open\") & (df[\"Amount\"] > 500)]\nnorth_or_south = df[(df[\"Region\"] == \"North\") | (df[\"Region\"] == \"South\")]\nnot_cancelled = df[~(df[\"Status\"] == \"Cancelled\")]\nprint(len(north_open_big), len(north_or_south), len(not_cancelled))\n\ntry:\n    df[df[\"Region\"] == \"North\" and df[\"Status\"] == \"Open\"]\nexcept ValueError as err:\n    print(\"ValueError:\", str(err)[:60])\n",[19,581,582,637,671,696,717,721,730,759,774],{"__ignoreMap":44},[48,583,584,587,589,592,595,597,599,602,605,607,610,612,614,616,619,621,623,625,627,629,631,634],{"class":50,"line":51},[48,585,586],{"class":87},"north_open_big ",[48,588,110],{"class":83},[48,590,591],{"class":87}," df[(df[",[48,593,594],{"class":58},"\"Region\"",[48,596,198],{"class":87},[48,598,201],{"class":83},[48,600,601],{"class":58}," \"North\"",[48,603,604],{"class":87},") ",[48,606,25],{"class":83},[48,608,609],{"class":87}," (df[",[48,611,195],{"class":58},[48,613,198],{"class":87},[48,615,201],{"class":83},[48,617,618],{"class":58}," \"Open\"",[48,620,604],{"class":87},[48,622,25],{"class":83},[48,624,609],{"class":87},[48,626,240],{"class":58},[48,628,198],{"class":87},[48,630,245],{"class":83},[48,632,633],{"class":137}," 500",[48,635,636],{"class":87},")]\n",[48,638,639,642,644,646,648,650,652,654,656,658,660,662,664,666,669],{"class":50,"line":97},[48,640,641],{"class":87},"north_or_south ",[48,643,110],{"class":83},[48,645,591],{"class":87},[48,647,594],{"class":58},[48,649,198],{"class":87},[48,651,201],{"class":83},[48,653,601],{"class":58},[48,655,604],{"class":87},[48,657,571],{"class":83},[48,659,609],{"class":87},[48,661,594],{"class":58},[48,663,198],{"class":87},[48,665,201],{"class":83},[48,667,668],{"class":58}," \"South\"",[48,670,636],{"class":87},[48,672,673,676,678,680,682,685,687,689,691,694],{"class":50,"line":104},[48,674,675],{"class":87},"not_cancelled ",[48,677,110],{"class":83},[48,679,192],{"class":87},[48,681,575],{"class":83},[48,683,684],{"class":87},"(df[",[48,686,195],{"class":58},[48,688,198],{"class":87},[48,690,201],{"class":83},[48,692,693],{"class":58}," \"Cancelled\"",[48,695,636],{"class":87},[48,697,698,700,702,704,707,709,712,714],{"class":50,"line":134},[48,699,138],{"class":137},[48,701,258],{"class":87},[48,703,261],{"class":137},[48,705,706],{"class":87},"(north_open_big), ",[48,708,261],{"class":137},[48,710,711],{"class":87},"(north_or_south), ",[48,713,261],{"class":137},[48,715,716],{"class":87},"(not_cancelled))\n",[48,718,719],{"class":50,"line":144},[48,720,101],{"emptyLinePlaceholder":100},[48,722,724,727],{"class":50,"line":723},6,[48,725,726],{"class":83},"try",[48,728,729],{"class":87},":\n",[48,731,733,736,738,740,742,744,747,749,751,753,755,757],{"class":50,"line":732},7,[48,734,735],{"class":87},"    df[df[",[48,737,594],{"class":58},[48,739,198],{"class":87},[48,741,201],{"class":83},[48,743,601],{"class":58},[48,745,746],{"class":83}," and",[48,748,192],{"class":87},[48,750,195],{"class":58},[48,752,198],{"class":87},[48,754,201],{"class":83},[48,756,618],{"class":58},[48,758,251],{"class":87},[48,760,762,765,768,771],{"class":50,"line":761},8,[48,763,764],{"class":83},"except",[48,766,767],{"class":137}," ValueError",[48,769,770],{"class":83}," as",[48,772,773],{"class":87}," err:\n",[48,775,777,780,782,785,787,790,793,796],{"class":50,"line":776},9,[48,778,779],{"class":137},"    print",[48,781,258],{"class":87},[48,783,784],{"class":58},"\"ValueError:\"",[48,786,119],{"class":87},[48,788,789],{"class":137},"str",[48,791,792],{"class":87},"(err)[:",[48,794,795],{"class":137},"60",[48,797,798],{"class":87},"])\n",[10,800,801,802,804,805,808,809,811,812,814,815,818,819,822],{},"Python's ",[19,803,21],{}," and ",[19,806,807],{},"or"," need a single True or False, and a whole column is neither, so pandas raises \"The truth value of a Series is ambiguous\". The brackets matter because ",[19,810,25],{}," binds more tightly than ",[19,813,201],{},": without them, ",[19,816,817],{},"df[\"Region\"] == \"North\" & df[\"Status\"] == \"Open\""," is evaluated as ",[19,820,821],{},"df[\"Region\"] == (\"North\" & df[\"Status\"]) == \"Open\"",", which either raises a type error or, with numeric columns, quietly computes something else. Brackets around every comparison make the intent unambiguous.",[34,824,826],{"id":825},"step-3-lists-ranges-and-dates","Step 3 — Lists, ranges and dates",[10,828,829,830,833,834,836,837,840],{},"For \"any of these values\", ",[19,831,832],{},"isin"," is shorter and faster than a chain of ",[19,835,571],{},". For ranges, ",[19,838,839],{},"between"," includes both ends by default:",[39,842,844],{"className":74,"code":843,"language":76,"meta":44,"style":44},"key_accounts = df[df[\"Customer\"].isin([\"Arden Ltd\", \"Cobalt GmbH\"])]\nmid_size = df[df[\"Amount\"].between(500, 1500)]\nseptember = df[(df[\"Date\"] >= \"2026-09-01\") & (df[\"Date\"] \u003C \"2026-10-01\")]\nprint(len(key_accounts), len(mid_size), len(september))\nprint(september[\"Date\"].min().date(), \"to\", september[\"Date\"].max().date())\n",[19,845,846,872,896,934,955],{"__ignoreMap":44},[48,847,848,851,853,855,858,861,864,866,869],{"class":50,"line":51},[48,849,850],{"class":87},"key_accounts ",[48,852,110],{"class":83},[48,854,237],{"class":87},[48,856,857],{"class":58},"\"Customer\"",[48,859,860],{"class":87},"].isin([",[48,862,863],{"class":58},"\"Arden Ltd\"",[48,865,119],{"class":87},[48,867,868],{"class":58},"\"Cobalt GmbH\"",[48,870,871],{"class":87},"])]\n",[48,873,874,877,879,881,883,886,889,891,894],{"class":50,"line":97},[48,875,876],{"class":87},"mid_size ",[48,878,110],{"class":83},[48,880,237],{"class":87},[48,882,240],{"class":58},[48,884,885],{"class":87},"].between(",[48,887,888],{"class":137},"500",[48,890,119],{"class":87},[48,892,893],{"class":137},"1500",[48,895,636],{"class":87},[48,897,898,901,903,905,908,910,913,916,918,920,922,924,926,929,932],{"class":50,"line":104},[48,899,900],{"class":87},"september ",[48,902,110],{"class":83},[48,904,591],{"class":87},[48,906,907],{"class":58},"\"Date\"",[48,909,198],{"class":87},[48,911,912],{"class":83},">=",[48,914,915],{"class":58}," \"2026-09-01\"",[48,917,604],{"class":87},[48,919,25],{"class":83},[48,921,609],{"class":87},[48,923,907],{"class":58},[48,925,198],{"class":87},[48,927,928],{"class":83},"\u003C",[48,930,931],{"class":58}," \"2026-10-01\"",[48,933,636],{"class":87},[48,935,936,938,940,942,945,947,950,952],{"class":50,"line":134},[48,937,138],{"class":137},[48,939,258],{"class":87},[48,941,261],{"class":137},[48,943,944],{"class":87},"(key_accounts), ",[48,946,261],{"class":137},[48,948,949],{"class":87},"(mid_size), ",[48,951,261],{"class":137},[48,953,954],{"class":87},"(september))\n",[48,956,957,959,962,964,967,970,973,975],{"class":50,"line":144},[48,958,138],{"class":137},[48,960,961],{"class":87},"(september[",[48,963,907],{"class":58},[48,965,966],{"class":87},"].min().date(), ",[48,968,969],{"class":58},"\"to\"",[48,971,972],{"class":87},", september[",[48,974,907],{"class":58},[48,976,977],{"class":87},"].max().date())\n",[10,979,980,981,983,984,987,988,991,992,994,995,998,999,119,1002,119,1005,119,1008,1011],{},"Comparing a datetime column with a date string works because pandas converts the string. Use a half-open range — on or after the 1st, ",[14,982,528],{}," the 1st of the next month — rather than ",[19,985,986],{},"\u003C= \"2026-09-30\"",": if the column carries times, a timestamp like 30 September 14:00 is later than ",[19,989,990],{},"\"2026-09-30\""," (midnight) and would be dropped. ",[19,993,839],{}," has an ",[19,996,997],{},"inclusive="," argument (",[19,1000,1001],{},"\"both\"",[19,1003,1004],{},"\"left\"",[19,1006,1007],{},"\"right\"",[19,1009,1010],{},"\"neither\"",") for the same reason.",[296,1013,305,1019,305,1022,305,1025,305,1029,305,1034,305,1039,305,1045,305,1048,305,1052,305,1056,305,1061,305,1063,305,1068,305,1070,305,1073,305,1076,305,1080,305,1082,305,1085,305,1087,305,1089,305,1092,305,1096,305,1098,305,1102,305,1104,305,1106,305,1109,305,1113,305,1115,305,1119,305,1121,305,1124,305,1127,305,1131,305,1133,305,1137,305,1139,305,1142,305,1145,305,1149,305,1151,305,1155,305,1157],{"viewBox":1014,"role":299,"ariaLabelledBy":1015,"xmlns":303,"style":1018},"4 0 752 276",[1016,1017],"fl-methods-t","fl-methods-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[307,1020,1021],{"id":1016},"Which mask-building method for which condition",[311,1023,1024],{"id":1017},"A table of common filter conditions and the pandas expression that builds each mask, with notes on missing values.",[315,1026],{"x":436,"y":318,"width":1027,"height":1028,"fill":321},"752","276",[315,1030],{"x":1031,"y":1032,"width":1033,"height":325,"rx":318,"fill":321,"stroke":329,"style":330},"20.0","16.0","169.3",[315,1035],{"x":1036,"y":1032,"width":1037,"height":325,"rx":318,"fill":1038,"stroke":538,"style":552},"189.3","275.4","#f0f4ff",[336,1040,1044],{"x":1041,"y":1042,"style":1043},"327.0","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Expression",[315,1046],{"x":1047,"y":1032,"width":1037,"height":325,"rx":318,"fill":1038,"stroke":538,"style":552},"464.6",[336,1049,1051],{"x":1050,"y":1042,"style":1043},"602.3","Blank cells",[315,1053],{"x":1031,"y":1054,"width":1033,"height":1055,"rx":318,"fill":328,"stroke":329,"style":330},"56.0","34.0",[336,1057,1060],{"x":326,"y":1058,"style":1059},"78.0","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start","equals \u002F compare",[315,1062],{"x":1036,"y":1054,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1064,1067],{"x":1041,"y":1065,"style":1066},"77.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","col == x, col > x",[315,1069],{"x":1047,"y":1054,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1071,1072],{"x":1050,"y":1065,"style":1066},"never match",[315,1074],{"x":1031,"y":1075,"width":1033,"height":1055,"rx":318,"fill":328,"stroke":329,"style":330},"90.0",[336,1077,1079],{"x":326,"y":1078,"style":1059},"112.0","any of a list",[315,1081],{"x":1036,"y":1075,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1083,1084],{"x":1041,"y":388,"style":1066},"col.isin([...])",[315,1086],{"x":1047,"y":1075,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1088,1072],{"x":1050,"y":388,"style":1066},[315,1090],{"x":1031,"y":1091,"width":1033,"height":1055,"rx":318,"fill":328,"stroke":329,"style":330},"124.0",[336,1093,1095],{"x":326,"y":1094,"style":1059},"146.0","numeric or date range",[315,1097],{"x":1036,"y":1091,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1099,1101],{"x":1041,"y":1100,"style":1066},"145.0","col.between(a, b)",[315,1103],{"x":1047,"y":1091,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1105,1072],{"x":1050,"y":1100,"style":1066},[315,1107],{"x":1031,"y":1108,"width":1033,"height":1055,"rx":318,"fill":328,"stroke":329,"style":330},"158.0",[336,1110,1112],{"x":326,"y":1111,"style":1059},"180.0","contains text",[315,1114],{"x":1036,"y":1108,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1116,1118],{"x":1041,"y":1117,"style":1066},"179.0","col.str.contains(s, na=False)",[315,1120],{"x":1047,"y":1108,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1122,1123],{"x":1050,"y":1117,"style":1066},"need na=False",[315,1125],{"x":1031,"y":1126,"width":1033,"height":1055,"rx":318,"fill":328,"stroke":329,"style":330},"192.0",[336,1128,1130],{"x":326,"y":1129,"style":1059},"214.0","is blank \u002F not blank",[315,1132],{"x":1036,"y":1126,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1134,1136],{"x":1041,"y":1135,"style":1066},"213.0","col.isna(), col.notna()",[315,1138],{"x":1047,"y":1126,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1140,1141],{"x":1050,"y":1135,"style":1066},"the point",[315,1143],{"x":1031,"y":1144,"width":1033,"height":1055,"rx":318,"fill":328,"stroke":329,"style":330},"226.0",[336,1146,1148],{"x":326,"y":1147,"style":1059},"248.0","not",[315,1150],{"x":1036,"y":1144,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1152,1154],{"x":1041,"y":1153,"style":1066},"247.0","~mask",[315,1156],{"x":1047,"y":1144,"width":1037,"height":1055,"rx":318,"fill":321,"stroke":329,"style":330},[336,1158,1159],{"x":1050,"y":1153,"style":1066},"flips to match",[34,1161,1163],{"id":1162},"step-4-text-conditions-that-survive-blanks","Step 4 — Text conditions that survive blanks",[10,1165,1166,1169,1170,1172,1173,1176],{},[19,1167,1168],{},"str.contains"," finds a substring or a pattern. What it does with blank cells depends on the column's type. pandas 3 reads text into its new string dtype, where a blank simply does not contain anything and the mask gets ",[19,1171,163],{},". In pandas 2, or in any column with the older ",[19,1174,1175],{},"object"," dtype — common when a column mixes text and numbers — blanks produce a missing value in the mask, and selecting with it fails:",[39,1178,1180],{"className":74,"code":1179,"language":76,"meta":44,"style":44},"print(df[\"Note\"].dtype, df[\"Note\"].str.contains(\"urgent\").isna().sum(), \"missing in the mask\")\n\nas_object = df[\"Note\"].astype(object)\ntry:\n    df[as_object.str.contains(\"urgent\")]\nexcept ValueError as err:\n    print(\"ValueError:\", err)\n\nurgent = df[df[\"Note\"].str.contains(\"urgent\", case=False, na=False)]\nprint(len(urgent), \"urgent:\", urgent[\"Note\"].unique().tolist())\narden = df[df[\"Customer\"].str.lower().str.startswith(\"arden\")]\nprint(arden[\"Customer\"].unique().tolist())\n",[19,1181,1182,1210,1214,1232,1238,1247,1257,1268,1272,1307,1330,1350],{"__ignoreMap":44},[48,1183,1184,1186,1188,1191,1194,1196,1199,1202,1205,1208],{"class":50,"line":51},[48,1185,138],{"class":137},[48,1187,684],{"class":87},[48,1189,1190],{"class":58},"\"Note\"",[48,1192,1193],{"class":87},"].dtype, df[",[48,1195,1190],{"class":58},[48,1197,1198],{"class":87},"].str.contains(",[48,1200,1201],{"class":58},"\"urgent\"",[48,1203,1204],{"class":87},").isna().sum(), ",[48,1206,1207],{"class":58},"\"missing in the mask\"",[48,1209,131],{"class":87},[48,1211,1212],{"class":50,"line":97},[48,1213,101],{"emptyLinePlaceholder":100},[48,1215,1216,1219,1221,1223,1225,1228,1230],{"class":50,"line":104},[48,1217,1218],{"class":87},"as_object ",[48,1220,110],{"class":83},[48,1222,192],{"class":87},[48,1224,1190],{"class":58},[48,1226,1227],{"class":87},"].astype(",[48,1229,1175],{"class":137},[48,1231,131],{"class":87},[48,1233,1234,1236],{"class":50,"line":134},[48,1235,726],{"class":83},[48,1237,729],{"class":87},[48,1239,1240,1243,1245],{"class":50,"line":144},[48,1241,1242],{"class":87},"    df[as_object.str.contains(",[48,1244,1201],{"class":58},[48,1246,636],{"class":87},[48,1248,1249,1251,1253,1255],{"class":50,"line":723},[48,1250,764],{"class":83},[48,1252,767],{"class":137},[48,1254,770],{"class":83},[48,1256,773],{"class":87},[48,1258,1259,1261,1263,1265],{"class":50,"line":732},[48,1260,779],{"class":137},[48,1262,258],{"class":87},[48,1264,784],{"class":58},[48,1266,1267],{"class":87},", err)\n",[48,1269,1270],{"class":50,"line":761},[48,1271,101],{"emptyLinePlaceholder":100},[48,1273,1274,1277,1279,1281,1283,1285,1287,1289,1292,1294,1296,1298,1301,1303,1305],{"class":50,"line":776},[48,1275,1276],{"class":87},"urgent ",[48,1278,110],{"class":83},[48,1280,237],{"class":87},[48,1282,1190],{"class":58},[48,1284,1198],{"class":87},[48,1286,1201],{"class":58},[48,1288,119],{"class":87},[48,1290,1291],{"class":122},"case",[48,1293,110],{"class":83},[48,1295,163],{"class":137},[48,1297,119],{"class":87},[48,1299,1300],{"class":122},"na",[48,1302,110],{"class":83},[48,1304,163],{"class":137},[48,1306,636],{"class":87},[48,1308,1310,1312,1314,1316,1319,1322,1325,1327],{"class":50,"line":1309},10,[48,1311,138],{"class":137},[48,1313,258],{"class":87},[48,1315,261],{"class":137},[48,1317,1318],{"class":87},"(urgent), ",[48,1320,1321],{"class":58},"\"urgent:\"",[48,1323,1324],{"class":87},", urgent[",[48,1326,1190],{"class":58},[48,1328,1329],{"class":87},"].unique().tolist())\n",[48,1331,1333,1336,1338,1340,1342,1345,1348],{"class":50,"line":1332},11,[48,1334,1335],{"class":87},"arden ",[48,1337,110],{"class":83},[48,1339,237],{"class":87},[48,1341,857],{"class":58},[48,1343,1344],{"class":87},"].str.lower().str.startswith(",[48,1346,1347],{"class":58},"\"arden\"",[48,1349,636],{"class":87},[48,1351,1353,1355,1358,1360],{"class":50,"line":1352},12,[48,1354,138],{"class":137},[48,1356,1357],{"class":87},"(arden[",[48,1359,857],{"class":58},[48,1361,1329],{"class":87},[10,1363,1364,1365,1368,1369,1371,1372,1375,1376,1379,1380,804,1383,1386,1387,1390,1391,1394,1395,1398],{},"Passing ",[19,1366,1367],{},"na=False"," makes the behaviour the same everywhere, so write it by habit — a script that works on your machine with pandas 3 should not break on a colleague's pandas 2 installation. ",[19,1370,1367],{}," treats blanks as \"does not contain\", and ",[19,1373,1374],{},"case=False"," makes ",[19,1377,1378],{},"URGENT - call"," match too. ",[19,1381,1382],{},"str.startswith",[19,1384,1385],{},"str.endswith"," cover the other common text conditions; lower-casing first catches the inconsistent ",[19,1388,1389],{},"arden ltd (EU)"," spelling. Watch out for regular-expression characters: ",[19,1392,1393],{},"str.contains(\"(EU)\")"," treats the brackets as a group, so pass ",[19,1396,1397],{},"regex=False"," for literal text.",[34,1400,1402],{"id":1401},"step-5-query-filters-as-readable-strings","Step 5 — query: filters as readable strings",[10,1404,1405,1408,1409,119,1411,804,1413,1415],{},[19,1406,1407],{},"DataFrame.query"," takes the whole condition as one string, which reads closer to how people describe filters — and uses ",[19,1410,21],{},[19,1412,807],{},[19,1414,1148],{},":",[39,1417,1419],{"className":74,"code":1418,"language":76,"meta":44,"style":44},"threshold = 750\nresult = df.query(\"Region in ['North', 'East'] and Status != 'Cancelled' and Amount > @threshold\")\nprint(len(result))\nprint(result[[\"OrderID\", \"Region\", \"Status\", \"Amount\"]].head().to_string(index=False))\n",[19,1420,1421,1431,1446,1457],{"__ignoreMap":44},[48,1422,1423,1426,1428],{"class":50,"line":51},[48,1424,1425],{"class":87},"threshold ",[48,1427,110],{"class":83},[48,1429,1430],{"class":137}," 750\n",[48,1432,1433,1436,1438,1441,1444],{"class":50,"line":97},[48,1434,1435],{"class":87},"result ",[48,1437,110],{"class":83},[48,1439,1440],{"class":87}," df.query(",[48,1442,1443],{"class":58},"\"Region in ['North', 'East'] and Status != 'Cancelled' and Amount > @threshold\"",[48,1445,131],{"class":87},[48,1447,1448,1450,1452,1454],{"class":50,"line":104},[48,1449,138],{"class":137},[48,1451,258],{"class":87},[48,1453,261],{"class":137},[48,1455,1456],{"class":87},"(result))\n",[48,1458,1459,1461,1464,1467,1469,1471,1473,1475,1477,1479,1482,1484,1486,1488],{"class":50,"line":134},[48,1460,138],{"class":137},[48,1462,1463],{"class":87},"(result[[",[48,1465,1466],{"class":58},"\"OrderID\"",[48,1468,119],{"class":87},[48,1470,594],{"class":58},[48,1472,119],{"class":87},[48,1474,195],{"class":58},[48,1476,119],{"class":87},[48,1478,240],{"class":58},[48,1480,1481],{"class":87},"]].head().to_string(",[48,1483,158],{"class":122},[48,1485,110],{"class":83},[48,1487,163],{"class":137},[48,1489,166],{"class":87},[10,1491,1492,1495,1496,1499,1500,1503],{},[19,1493,1494],{},"@threshold"," refers to a Python variable. Column names with spaces need backticks inside the string: ",[19,1497,1498],{},"query(\"`Order Value` > 100\")",". ",[19,1501,1502],{},"query"," is convenient for filters that are typed by a person or stored as text; for filters built in code, masks are easier to compose and debug.",[34,1505,1507],{"id":1506},"step-6-filters-from-a-configuration-file","Step 6 — Filters from a configuration file",[10,1509,1510],{},"Report jobs often run the same filter with different values each month or for each recipient. Keep the conditions as data and turn them into one mask:",[39,1512,1514],{"className":74,"code":1513,"language":76,"meta":44,"style":44},"FILTERS = {\n    \"Status\": {\"in\": [\"Open\", \"Shipped\"]},\n    \"Amount\": {\"min\": 250},\n    \"Date\": {\"min\": \"2026-08-15\", \"max_before\": \"2026-09-15\"},\n}\n\ndef apply_filters(frame, spec):\n    mask = pd.Series(True, index=frame.index)\n    for col, rule in spec.items():\n        if \"in\" in rule:\n            mask &= frame[col].isin(rule[\"in\"])\n        if \"min\" in rule:\n            mask &= frame[col] >= rule[\"min\"]\n        if \"max_before\" in rule:\n            mask &= frame[col] \u003C rule[\"max_before\"]\n    return frame[mask]\n\nselected = apply_filters(df, FILTERS)\nprint(len(selected), \"rows match the configured filter\")\n",[19,1515,1516,1527,1552,1571,1597,1602,1606,1618,1639,1653,1667,1682,1693,1712,1724,1741,1750,1755,1770],{"__ignoreMap":44},[48,1517,1518,1521,1524],{"class":50,"line":51},[48,1519,1520],{"class":137},"FILTERS",[48,1522,1523],{"class":83}," =",[48,1525,1526],{"class":87}," {\n",[48,1528,1529,1532,1535,1538,1541,1544,1546,1549],{"class":50,"line":97},[48,1530,1531],{"class":58},"    \"Status\"",[48,1533,1534],{"class":87},": {",[48,1536,1537],{"class":58},"\"in\"",[48,1539,1540],{"class":87},": [",[48,1542,1543],{"class":58},"\"Open\"",[48,1545,119],{"class":87},[48,1547,1548],{"class":58},"\"Shipped\"",[48,1550,1551],{"class":87},"]},\n",[48,1553,1554,1557,1559,1562,1565,1568],{"class":50,"line":104},[48,1555,1556],{"class":58},"    \"Amount\"",[48,1558,1534],{"class":87},[48,1560,1561],{"class":58},"\"min\"",[48,1563,1564],{"class":87},": ",[48,1566,1567],{"class":137},"250",[48,1569,1570],{"class":87},"},\n",[48,1572,1573,1576,1578,1580,1582,1585,1587,1590,1592,1595],{"class":50,"line":134},[48,1574,1575],{"class":58},"    \"Date\"",[48,1577,1534],{"class":87},[48,1579,1561],{"class":58},[48,1581,1564],{"class":87},[48,1583,1584],{"class":58},"\"2026-08-15\"",[48,1586,119],{"class":87},[48,1588,1589],{"class":58},"\"max_before\"",[48,1591,1564],{"class":87},[48,1593,1594],{"class":58},"\"2026-09-15\"",[48,1596,1570],{"class":87},[48,1598,1599],{"class":50,"line":144},[48,1600,1601],{"class":87},"}\n",[48,1603,1604],{"class":50,"line":723},[48,1605,101],{"emptyLinePlaceholder":100},[48,1607,1608,1611,1615],{"class":50,"line":732},[48,1609,1610],{"class":83},"def",[48,1612,1614],{"class":1613},"s_Opv"," apply_filters",[48,1616,1617],{"class":87},"(frame, spec):\n",[48,1619,1620,1623,1625,1628,1630,1632,1634,1636],{"class":50,"line":761},[48,1621,1622],{"class":87},"    mask ",[48,1624,110],{"class":83},[48,1626,1627],{"class":87}," pd.Series(",[48,1629,409],{"class":137},[48,1631,119],{"class":87},[48,1633,158],{"class":122},[48,1635,110],{"class":83},[48,1637,1638],{"class":87},"frame.index)\n",[48,1640,1641,1644,1647,1650],{"class":50,"line":776},[48,1642,1643],{"class":83},"    for",[48,1645,1646],{"class":87}," col, rule ",[48,1648,1649],{"class":83},"in",[48,1651,1652],{"class":87}," spec.items():\n",[48,1654,1655,1658,1661,1664],{"class":50,"line":1309},[48,1656,1657],{"class":83},"        if",[48,1659,1660],{"class":58}," \"in\"",[48,1662,1663],{"class":83}," in",[48,1665,1666],{"class":87}," rule:\n",[48,1668,1669,1672,1675,1678,1680],{"class":50,"line":1332},[48,1670,1671],{"class":87},"            mask ",[48,1673,1674],{"class":83},"&=",[48,1676,1677],{"class":87}," frame[col].isin(rule[",[48,1679,1537],{"class":58},[48,1681,798],{"class":87},[48,1683,1684,1686,1689,1691],{"class":50,"line":1352},[48,1685,1657],{"class":83},[48,1687,1688],{"class":58}," \"min\"",[48,1690,1663],{"class":83},[48,1692,1666],{"class":87},[48,1694,1696,1698,1700,1703,1705,1708,1710],{"class":50,"line":1695},13,[48,1697,1671],{"class":87},[48,1699,1674],{"class":83},[48,1701,1702],{"class":87}," frame[col] ",[48,1704,912],{"class":83},[48,1706,1707],{"class":87}," rule[",[48,1709,1561],{"class":58},[48,1711,251],{"class":87},[48,1713,1715,1717,1720,1722],{"class":50,"line":1714},14,[48,1716,1657],{"class":83},[48,1718,1719],{"class":58}," \"max_before\"",[48,1721,1663],{"class":83},[48,1723,1666],{"class":87},[48,1725,1727,1729,1731,1733,1735,1737,1739],{"class":50,"line":1726},15,[48,1728,1671],{"class":87},[48,1730,1674],{"class":83},[48,1732,1702],{"class":87},[48,1734,928],{"class":83},[48,1736,1707],{"class":87},[48,1738,1589],{"class":58},[48,1740,251],{"class":87},[48,1742,1744,1747],{"class":50,"line":1743},16,[48,1745,1746],{"class":83},"    return",[48,1748,1749],{"class":87}," frame[mask]\n",[48,1751,1753],{"class":50,"line":1752},17,[48,1754,101],{"emptyLinePlaceholder":100},[48,1756,1758,1761,1763,1766,1768],{"class":50,"line":1757},18,[48,1759,1760],{"class":87},"selected ",[48,1762,110],{"class":83},[48,1764,1765],{"class":87}," apply_filters(df, ",[48,1767,1520],{"class":137},[48,1769,131],{"class":87},[48,1771,1773,1775,1777,1779,1782,1785],{"class":50,"line":1772},19,[48,1774,138],{"class":137},[48,1776,258],{"class":87},[48,1778,261],{"class":137},[48,1780,1781],{"class":87},"(selected), ",[48,1783,1784],{"class":58},"\"rows match the configured filter\"",[48,1786,131],{"class":87},[10,1788,1789,1790,1792,1793,1797],{},"Starting from an all-True mask and narrowing it with ",[19,1791,1674],{}," makes each rule optional. The dictionary can come from a YAML or JSON file that non-developers edit, as described in ",[28,1794,1796],{"href":1795},"\u002Fautomating-reporting-workflows\u002Ftesting-and-packaging-excel-automation-scripts\u002Fkeep-excel-report-settings-in-a-config-file\u002F","Keep Excel Report Settings in a Config File",".",[34,1799,1801],{"id":1800},"step-7-filter-a-formatted-workbook-in-place","Step 7 — Filter a formatted workbook in place",[10,1803,1804,1805,1808],{},"Writing ",[19,1806,1807],{},"selected.to_excel(...)"," produces a new sheet without the original formatting. When the workbook's look must survive — a styled header, number formats, column widths — delete the non-matching rows with openpyxl instead, working from the bottom up so row numbers do not shift under the loop:",[39,1810,1812],{"className":74,"code":1811,"language":76,"meta":44,"style":44},"from openpyxl import load_workbook\n\nkeep_ids = set(df.loc[df[\"Status\"] == \"Open\", \"OrderID\"])\nwb = load_workbook(\"orders.xlsx\")\nws = wb[\"Orders\"]\nfor r in range(ws.max_row, 1, -1):\n    if ws.cell(r, 1).value not in keep_ids:\n        ws.delete_rows(r)\nwb.save(\"orders_open.xlsx\")\n\ncheck = load_workbook(\"orders_open.xlsx\")[\"Orders\"]\nprint(check.max_row - 1, \"rows kept; header bold:\", check[\"A1\"].font.b, \"; date format:\", check[\"B2\"].number_format)\n",[19,1813,1814,1827,1831,1858,1872,1886,1914,1934,1939,1949,1953,1971],{"__ignoreMap":44},[48,1815,1816,1819,1822,1824],{"class":50,"line":51},[48,1817,1818],{"class":83},"from",[48,1820,1821],{"class":87}," openpyxl ",[48,1823,84],{"class":83},[48,1825,1826],{"class":87}," load_workbook\n",[48,1828,1829],{"class":50,"line":97},[48,1830,101],{"emptyLinePlaceholder":100},[48,1832,1833,1836,1838,1841,1844,1846,1848,1850,1852,1854,1856],{"class":50,"line":104},[48,1834,1835],{"class":87},"keep_ids ",[48,1837,110],{"class":83},[48,1839,1840],{"class":137}," set",[48,1842,1843],{"class":87},"(df.loc[df[",[48,1845,195],{"class":58},[48,1847,198],{"class":87},[48,1849,201],{"class":83},[48,1851,618],{"class":58},[48,1853,119],{"class":87},[48,1855,1466],{"class":58},[48,1857,798],{"class":87},[48,1859,1860,1863,1865,1868,1870],{"class":50,"line":134},[48,1861,1862],{"class":87},"wb ",[48,1864,110],{"class":83},[48,1866,1867],{"class":87}," load_workbook(",[48,1869,116],{"class":58},[48,1871,131],{"class":87},[48,1873,1874,1877,1879,1882,1884],{"class":50,"line":144},[48,1875,1876],{"class":87},"ws ",[48,1878,110],{"class":83},[48,1880,1881],{"class":87}," wb[",[48,1883,128],{"class":58},[48,1885,251],{"class":87},[48,1887,1888,1891,1894,1896,1899,1902,1904,1906,1909,1911],{"class":50,"line":723},[48,1889,1890],{"class":83},"for",[48,1892,1893],{"class":87}," r ",[48,1895,1649],{"class":83},[48,1897,1898],{"class":137}," range",[48,1900,1901],{"class":87},"(ws.max_row, ",[48,1903,366],{"class":137},[48,1905,119],{"class":87},[48,1907,1908],{"class":83},"-",[48,1910,366],{"class":137},[48,1912,1913],{"class":87},"):\n",[48,1915,1916,1919,1922,1924,1927,1929,1931],{"class":50,"line":732},[48,1917,1918],{"class":83},"    if",[48,1920,1921],{"class":87}," ws.cell(r, ",[48,1923,366],{"class":137},[48,1925,1926],{"class":87},").value ",[48,1928,1148],{"class":83},[48,1930,1663],{"class":83},[48,1932,1933],{"class":87}," keep_ids:\n",[48,1935,1936],{"class":50,"line":761},[48,1937,1938],{"class":87},"        ws.delete_rows(r)\n",[48,1940,1941,1944,1947],{"class":50,"line":776},[48,1942,1943],{"class":87},"wb.save(",[48,1945,1946],{"class":58},"\"orders_open.xlsx\"",[48,1948,131],{"class":87},[48,1950,1951],{"class":50,"line":1309},[48,1952,101],{"emptyLinePlaceholder":100},[48,1954,1955,1958,1960,1962,1964,1967,1969],{"class":50,"line":1332},[48,1956,1957],{"class":87},"check ",[48,1959,110],{"class":83},[48,1961,1867],{"class":87},[48,1963,1946],{"class":58},[48,1965,1966],{"class":87},")[",[48,1968,128],{"class":58},[48,1970,251],{"class":87},[48,1972,1973,1975,1978,1980,1983,1985,1988,1991,1994,1997,2000,2002,2005],{"class":50,"line":1352},[48,1974,138],{"class":137},[48,1976,1977],{"class":87},"(check.max_row ",[48,1979,1908],{"class":83},[48,1981,1982],{"class":137}," 1",[48,1984,119],{"class":87},[48,1986,1987],{"class":58},"\"rows kept; header bold:\"",[48,1989,1990],{"class":87},", check[",[48,1992,1993],{"class":58},"\"A1\"",[48,1995,1996],{"class":87},"].font.b, ",[48,1998,1999],{"class":58},"\"; date format:\"",[48,2001,1990],{"class":87},[48,2003,2004],{"class":58},"\"B2\"",[48,2006,2007],{"class":87},"].number_format)\n",[296,2009,305,2014,305,2017,305,2020,305,2023,305,2028,305,2039,305,2045,305,2049,305,2053,305,2058,305,2061,305,2064,305,2071,305,2076,305,2080,305,2083,305,2087,305,2090,305,2093,305,2099,305,2104,305,2108,305,2112,305,2116,305,2119,305,2122,305,2127,305,2134,305,2139,305,2142,305,2145,305,2148,305,2152,305,2155,305,2158,305,2165,305,2170,305,2173],{"viewBox":2010,"role":299,"ariaLabelledBy":2011,"xmlns":303,"style":1018},"4 0 752 160",[2012,2013],"fl-inplace-t","fl-inplace-d",[307,2015,2016],{"id":2012},"Decide in pandas, delete in openpyxl",[311,2018,2019],{"id":2013},"pandas reads the sheet and computes the set of order IDs to keep, openpyxl opens the original workbook and deletes the other rows from the bottom up, and the saved file keeps its styles.",[315,2021],{"x":436,"y":318,"width":1027,"height":2022,"fill":321},"160",[315,2024],{"x":1031,"y":1032,"width":2025,"height":2026,"rx":2027,"fill":328,"stroke":329,"style":539},"115.2","128.0","12",[2029,2030,2032],"g",{"transform":2031},"translate(65.6,37.8) scale(1.000)",[2033,2034],"path",{"d":2035,"fill":2036,"stroke":2037,"style":2038},"M3 5h18v14H3z M3 10h18 M3 15h18 M9 5v14","none","var(--text,#172033)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[336,2040,2044],{"x":2041,"y":2042,"style":2043},"77.6","84.2","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Read with",[336,2046,2048],{"x":2041,"y":2047,"style":2043},"101.8","pandas",[336,2050,2052],{"x":2041,"y":2051,"style":1066},"121.2","build the mask",[50,2054],{"x1":2055,"y1":2056,"x2":2057,"y2":2056,"stroke":538,"style":539},"140.2","80.0","162.2",[541,2059],{"points":2060,"fill":544},"166.2,80.0 157.2,85.0 157.2,75.0",[315,2062],{"x":2063,"y":1032,"width":2025,"height":2026,"rx":2027,"fill":1038,"stroke":538,"style":539},"171.2",[2029,2065,2067],{"transform":2066},"translate(216.8,37.8) scale(1.000)",[2033,2068],{"d":2069,"fill":2036,"stroke":2070,"style":2038},"M3 5h18l-7 8v6l-4 2v-8z","var(--brand-strong,#4338ca)",[336,2072,2075],{"x":2073,"y":2042,"style":2074},"228.8","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Keep set",[336,2077,2079],{"x":2073,"y":2078,"style":1066},"103.8","IDs of matching",[336,2081,2082],{"x":2073,"y":2051,"style":1066},"rows",[50,2084],{"x1":2085,"y1":2056,"x2":2086,"y2":2056,"stroke":538,"style":539},"291.4","313.4",[541,2088],{"points":2089,"fill":544},"317.4,80.0 308.4,85.0 308.4,75.0",[315,2091],{"x":2092,"y":1032,"width":2025,"height":2026,"rx":2027,"fill":1038,"stroke":538,"style":539},"322.4",[2029,2094,2096],{"transform":2095},"translate(368.0,29.0) scale(1.000)",[2033,2097],{"d":2098,"fill":2036,"stroke":2070,"style":2038},"M6 3h9l4 4v14H6z M15 3v4h4 M9.5 11.5l4.5 6 M14 11.5l-4.5 6",[336,2100,2103],{"x":2101,"y":2102,"style":2074},"380.0","75.5","Open with",[336,2105,2107],{"x":2101,"y":2106,"style":2074},"93.0","openpyxl",[336,2109,2111],{"x":2101,"y":2110,"style":1066},"112.5","the formatted",[336,2113,2115],{"x":2101,"y":2114,"style":1066},"130.0","original",[50,2117],{"x1":2118,"y1":2056,"x2":1047,"y2":2056,"stroke":538,"style":539},"442.6",[541,2120],{"points":2121,"fill":544},"468.6,80.0 459.6,85.0 459.6,75.0",[315,2123],{"x":2124,"y":1032,"width":2025,"height":2026,"rx":2027,"fill":2125,"stroke":2126,"style":539},"473.6","#fdefd8","var(--gold,#b4740a)",[2029,2128,2130],{"transform":2129},"translate(519.2,29.0) scale(1.000)",[2033,2131],{"d":2132,"fill":2036,"stroke":2133,"style":2038},"M4 7h16 M10 11v6 M14 11v6 M6 7l1 13h10l1-13 M9 7V4h6v3","var(--gold-ink,#7a4e06)",[336,2135,2138],{"x":2136,"y":2102,"style":2137},"531.2","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Delete",[336,2140,2141],{"x":2136,"y":2106,"style":2137},"bottom-up",[336,2143,2144],{"x":2136,"y":2110,"style":1066},"rows not in the",[336,2146,2147],{"x":2136,"y":2114,"style":1066},"set",[50,2149],{"x1":2150,"y1":2056,"x2":2151,"y2":2056,"stroke":538,"style":539},"593.8","615.8",[541,2153],{"points":2154,"fill":544},"619.8,80.0 610.8,85.0 610.8,75.0",[315,2156],{"x":2157,"y":1032,"width":2025,"height":2026,"rx":2027,"fill":403,"stroke":404,"style":539},"624.8",[2029,2159,2161],{"transform":2160},"translate(670.4,37.8) scale(1.000)",[2033,2162],{"d":2163,"fill":2036,"stroke":2164,"style":2038},"M5 12.5l4.5 4.5L19 7","var(--teal-ink,#0b6157)",[336,2166,2169],{"x":2167,"y":2042,"style":2168},"682.4","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Save",[336,2171,2172],{"x":2167,"y":2078,"style":1066},"styles and",[336,2174,2175],{"x":2167,"y":2051,"style":1066},"formats intact",[10,2177,2178,2179,2183,2184,1797],{},"The rule is decided in pandas, where conditions are easy, and applied in openpyxl, where formatting is kept. Deleting row by row is slow for tens of thousands of rows; for large sheets, write the filtered data into a copy of the template instead, as in ",[28,2180,2182],{"href":2181},"\u002Fautomating-reporting-workflows\u002Fgenerating-excel-reports-from-templates\u002Fpopulate-excel-template-without-losing-formatting\u002F","Populate an Excel Template Without Losing Formatting",". If the reader should be able to change the filter themselves, apply an AutoFilter instead of deleting anything — see ",[28,2185,2187],{"href":2186},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fapply-autofilter-criteria-and-hide-rows\u002F","Apply AutoFilter Criteria and Hide Rows",[34,2189,2191],{"id":2190},"common-pitfalls","Common pitfalls",[2193,2194,2195,2211,2217,2235,2249],"ul",{},[2196,2197,2198,2210],"li",{},[2199,2200,2201,2203,2204,22,2206,2203,2208,1797],"strong",{},[19,2202,21],{},"\u002F",[19,2205,807],{},[19,2207,25],{},[19,2209,571],{}," Raises \"truth value of a Series is ambiguous\".",[2196,2212,2213,2216],{},[2199,2214,2215],{},"Missing brackets around comparisons."," Operator precedence changes the meaning; bracket every condition.",[2196,2218,2219,2222,2223,2225,2226,119,2228,804,2231,2234],{},[2199,2220,2221],{},"Blank cells in text filters."," On object columns, and in pandas 2, blanks make the mask unusable. Pass ",[19,2224,1367],{}," to ",[19,2227,1168],{},[19,2229,2230],{},"startswith",[19,2232,2233],{},"endswith"," so the code works on every version.",[2196,2236,2237,2240,2241,2244,2245,2248],{},[2199,2238,2239],{},"Dates compared with an inclusive end."," Use ",[19,2242,2243],{},"\u003C next day"," rather than ",[19,2246,2247],{},"\u003C= last day"," when the column may have times.",[2196,2250,2251,2254,2255,2258,2259,2262,2263,2266],{},[2199,2252,2253],{},"Modifying a filtered slice."," ",[19,2256,2257],{},"subset = df[mask]"," followed by ",[19,2260,2261],{},"subset[\"x\"] = ..."," triggers a copy warning; call ",[19,2264,2265],{},".copy()"," when you intend to change the subset.",[34,2268,2270],{"id":2269},"conclusion","Conclusion",[10,2272,2273,2274,119,2276,119,2278,2281,2282,119,2284,804,2286,2288,2289,2291,2292,2294],{},"Build a boolean mask for each condition — comparisons, ",[19,2275,832],{},[19,2277,839],{},[19,2279,2280],{},"str.contains(..., na=False)"," — combine them with ",[19,2283,25],{},[19,2285,571],{},[19,2287,575],{}," with every condition in brackets, and select with ",[19,2290,558],{},". Use ",[19,2293,1502],{}," for filters written as text, a dictionary of rules for filters that change per run, and openpyxl row deletion when the filtered result must keep the workbook's formatting.",[34,2296,2298],{"id":2297},"frequently-asked-questions","Frequently asked questions",[10,2300,2301,2304,2305,2314],{},[2199,2302,2303],{},"How do I filter rows in pandas by multiple conditions?","\nCombine boolean masks with & for and, | for or and ~ for not, with each condition in brackets: df",[48,2306,2307,2308,2310,2311,2313],{},"(df",[48,2309,594],{}," == \"North\") & (df",[48,2312,240],{}," > 500)",". Python's and\u002For keywords do not work on whole columns.",[10,2316,2317,2320],{},[2199,2318,2319],{},"Why do I get \"The truth value of a Series is ambiguous\"?","\nYou used and, or or not between two conditions on columns. Replace them with &, | and ~, and put brackets around each comparison.",[10,2322,2323,2326,2327,2334],{},[2199,2324,2325],{},"How do I filter rows where a column contains text?","\nUse df",[48,2328,2329,2330,2333],{},"df",[48,2331,2332],{},"\"col\"",".str.contains(\"text\", case=False, na=False)",". na=False makes blank cells count as not matching on every pandas version and column type, and regex=False treats the search text literally.",[10,2336,2337,2340],{},[2199,2338,2339],{},"How do I filter an Excel file without losing its formatting?","\nDecide which rows to keep with pandas, then open the workbook with openpyxl and delete the other rows from the bottom up with ws.delete_rows, and save. The header styles, number formats and column widths stay as they were.",[34,2342,2344],{"id":2343},"related","Related",[2193,2346,2347,2353,2360,2367],{},[2196,2348,2349,2350,2352],{},"Up one level: ",[28,2351,31],{"href":30}," — the everyday clean-up toolkit.",[2196,2354,2355,2359],{},[28,2356,2358],{"href":2357},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fremove-blank-rows-from-excel-with-pandas\u002F","Remove Blank Rows from Excel with pandas"," — filtering out empty rows specifically.",[2196,2361,2362,2366],{},[28,2363,2365],{"href":2364},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fsplit-one-excel-sheet-into-multiple-files-by-value\u002F","Split One Excel Sheet into Multiple Files by Value"," — one filter per value, one file each.",[2196,2368,2369,2373],{},[28,2370,2372],{"href":2371},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Funique-sort-and-filter-equivalents-in-pandas\u002F","UNIQUE, SORT and FILTER Equivalents in pandas"," — Excel's FILTER function translated.",[2375,2376,2377],"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_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}",{"title":44,"searchDepth":97,"depth":97,"links":2379},[2380,2381,2382,2383,2384,2385,2386,2387,2388,2389,2390,2391],{"id":36,"depth":97,"text":37},{"id":169,"depth":97,"text":170},{"id":561,"depth":97,"text":562},{"id":825,"depth":97,"text":826},{"id":1162,"depth":97,"text":1163},{"id":1401,"depth":97,"text":1402},{"id":1506,"depth":97,"text":1507},{"id":1800,"depth":97,"text":1801},{"id":2190,"depth":97,"text":2191},{"id":2269,"depth":97,"text":2270},{"id":2297,"depth":97,"text":2298},{"id":2343,"depth":97,"text":2344},"2026-09-29","Keep only the rows you need from a sheet: boolean masks, combining conditions with & | ~ and the brackets they need, isin, between and date ranges, text matching that does not crash on blanks, query strings, filters defined in a config file, and deleting rows from a formatted workbook in place with openpyxl.","md",[2396,2398,2400,2402],{"q":2303,"a":2397},"Combine boolean masks with & for and, | for or and ~ for not, with each condition in brackets: df[(df[\"Region\"] == \"North\") & (df[\"Amount\"] > 500)]. Python's and\u002For keywords do not work on whole columns.",{"q":2319,"a":2399},"You used and, or or not between two conditions on columns. Replace them with &, | and ~, and put brackets around each comparison.",{"q":2325,"a":2401},"Use df[df[\"col\"].str.contains(\"text\", case=False, na=False)]. na=False makes blank cells count as not matching on every pandas version and column type, and regex=False treats the search text literally.",{"q":2339,"a":2403},"Decide which rows to keep with pandas, then open the workbook with openpyxl and delete the other rows from the bottom up with ws.delete_rows, and save. The header styles, number formats and column widths stay as they were.","filter excel rows by condition with pandas",null,{"breadcrumb":2407},[2408,2410,2413],{"name":2409,"item":2203},"Home",{"name":2411,"item":2412},"Advanced Data Transformation and Cleaning for Excel Automation","\u002Fadvanced-data-transformation-and-cleaning\u002F",{"name":2414,"item":30},"Cleaning Excel Data With Pandas: A Production Workflow","\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Ffilter-excel-rows-by-condition-with-pandas",{"title":2417,"description":2418},"Filter Excel Rows by Multiple Conditions in pandas","Filter rows from an Excel file with pandas: boolean masks with & and |, isin, between, date ranges, str.contains with na=False, DataFrame.query, config-driven filters, and removing non-matching rows from a formatted workbook with openpyxl.","filter-excel-rows-by-condition-with-pandas","advanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Ffilter-excel-rows-by-condition-with-pandas\u002Findex",[2422,2048],"data-cleaning","how-to","ImztdDfKw79Yj8U2HKbT9B5qIOcaStGZn3LJKGQ20qo",[2426,2430],{"title":2427,"path":2428,"stem":2429,"children":-1},"Extract Numbers and Codes from Text with pandas","\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fextract-numbers-and-codes-from-text-with-pandas","advanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fextract-numbers-and-codes-from-text-with-pandas\u002Findex",{"title":2431,"path":2432,"stem":2433,"children":-1},"Find Near-Duplicate Names Within One Excel Column","\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Ffind-near-duplicate-names-within-one-excel-column","advanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Ffind-near-duplicate-names-within-one-excel-column\u002Findex",[2435,2437],{"path":2436,"title":2414},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas",{"path":2438,"title":2411},"\u002Fadvanced-data-transformation-and-cleaning",[],[2441,2444,2447,2450,2453,2456],{"path":2442,"title":2443,"kind":2423},"\u002Fadvanced-data-transformation-and-cleaning\u002Fvalidating-excel-data-with-python\u002Ffind-duplicate-rows-in-excel-with-python","Find Duplicate Rows in Excel with Python",{"path":2445,"title":2446,"kind":2423},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fhighlight-duplicate-values-in-excel-with-openpyxl","Highlight Duplicate Values in Excel with openpyxl",{"path":2448,"title":2449,"kind":2423},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fclean-mixed-currency-amounts-into-amount-and-currency-columns","Clean Mixed-Currency Amounts into Amount and Currency Columns",{"path":2451,"title":2452,"kind":2423},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fcoalesce-several-excel-columns-into-one-with-pandas","Coalesce Several Excel Columns into One with pandas",{"path":2454,"title":2455,"kind":2423},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fconvert-currency-strings-to-numbers-with-pandas","Convert Currency Strings Like \"$1,234.56\" and \"(500)\" to Numbers with pandas",{"path":2457,"title":2458,"kind":2423},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fconvert-excel-text-columns-to-numbers-with-pandas","Convert Excel Text Columns to Numbers with pandas",1790972080703]