[{"data":1,"prerenderedAt":2146},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-could-not-convert-string-to-float-in-excel-data":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-could-not-convert-string-to-float-in-excel-data":2111,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-could-not-convert-string-to-float-in-excel-data":2120,"children:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-could-not-convert-string-to-float-in-excel-data":2125,"related:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-could-not-convert-string-to-float-in-excel-data":2126},{"id":4,"title":5,"body":6,"dateModified":2079,"datePublished":2079,"description":2080,"extension":2081,"faq":2082,"keyword":2091,"kind":2092,"meta":2093,"navigation":112,"path":2101,"seo":2102,"slug":2104,"stem":2105,"topics":2106,"type":2109,"__hash__":2110},"docs\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-could-not-convert-string-to-float-in-excel-data\u002Findex.md","Fix \"Could Not Convert String to Float\" in Excel Data",{"type":7,"value":8,"toc":2066},"minimark",[9,39,44,72,80,84,343,389,393,749,760,946,950,1498,1518,1690,1894,1898,1905,1909,1912,1916,1936,1940,1985,1989,2001,2005,2011,2017,2023,2029,2033,2062],[10,11,12,16,17,20,21,24,25,28,29,32,33,38],"p",{},[13,14,15],"code",{},"ValueError: could not convert string to float: '1,234.50'"," is one of the most common errors in Excel data work. It appears when a column that looks numeric in Excel turns out to contain text — usually because the data was typed, pasted from another system or exported as formatted strings. ",[13,18,19],{},"astype(float)"," stops at the first bad value and names only that one, so fixing it one error at a time is slow, and the tempting shortcut, ",[13,22,23],{},"pd.to_numeric(errors=\"coerce\")",", makes the error go away by turning every problem into ",[13,26,27],{},"NaN"," — including values that were perfectly good amounts written as ",[13,30,31],{},"€ 1.234,50",". This page finds every failing cell at once, groups the failures by cause, cleans the common formats deliberately, and reports what is still unconvertible so it can be fixed at the source rather than silently lost. It belongs to ",[34,35,37],"a",{"href":36},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002F","Troubleshooting Common Python Excel Errors",".",[40,41,43],"h2",{"id":42},"prerequisites","Prerequisites",[45,46,51],"pre",{"className":47,"code":48,"language":49,"meta":50,"style":50},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas openpyxl\n","bash","",[13,52,53],{"__ignoreMap":50},[54,55,58,62,66,69],"span",{"class":56,"line":57},"line",1,[54,59,61],{"class":60},"sMTad","pip",[54,63,65],{"class":64},"srMev"," install",[54,67,68],{"class":64}," pandas",[54,70,71],{"class":64}," openpyxl\n",[10,73,74,75,79],{},"The sample is an invoice export whose ",[76,77,78],"em",{},"Amount"," column mixes real numbers with text in a dozen formats — the state such columns are usually in when several people and systems have written to them.",[40,81,83],{"id":82},"step-1-reproduce-then-find-every-failing-value","Step 1 — Reproduce, then find every failing value",[45,85,89],{"className":86,"code":87,"language":88,"meta":50,"style":50},"language-python shiki shiki-themes github-light github-dark-high-contrast","import pandas as pd\n\ndf = pd.read_excel(\"invoices.xlsx\", keep_default_na=False)\ntry:\n    df[\"Amount\"].astype(float)\nexcept ValueError as e:\n    print(\"ValueError:\", e)\n\nconverted = pd.to_numeric(df[\"Amount\"], errors=\"coerce\")\nbad = df.loc[converted.isna(), [\"Invoice\", \"Amount\"]]\nprint(f\"{len(bad)} of {len(df)} values fail:\")\nprint(bad.assign(repr=bad[\"Amount\"].map(repr)).drop(columns=\"Amount\").to_string(index=False))\n","python",[13,90,91,107,114,145,154,171,186,201,206,232,253,297],{"__ignoreMap":50},[54,92,93,97,101,104],{"class":56,"line":57},[54,94,96],{"class":95},"s-kum","import",[54,98,100],{"class":99},"skGVy"," pandas ",[54,102,103],{"class":95},"as",[54,105,106],{"class":99}," pd\n",[54,108,110],{"class":56,"line":109},2,[54,111,113],{"emptyLinePlaceholder":112},true,"\n",[54,115,117,120,123,126,129,132,136,138,142],{"class":56,"line":116},3,[54,118,119],{"class":99},"df ",[54,121,122],{"class":95},"=",[54,124,125],{"class":99}," pd.read_excel(",[54,127,128],{"class":64},"\"invoices.xlsx\"",[54,130,131],{"class":99},", ",[54,133,135],{"class":134},"sa561","keep_default_na",[54,137,122],{"class":95},[54,139,141],{"class":140},"sP0c6","False",[54,143,144],{"class":99},")\n",[54,146,148,151],{"class":56,"line":147},4,[54,149,150],{"class":95},"try",[54,152,153],{"class":99},":\n",[54,155,157,160,163,166,169],{"class":56,"line":156},5,[54,158,159],{"class":99},"    df[",[54,161,162],{"class":64},"\"Amount\"",[54,164,165],{"class":99},"].astype(",[54,167,168],{"class":140},"float",[54,170,144],{"class":99},[54,172,174,177,180,183],{"class":56,"line":173},6,[54,175,176],{"class":95},"except",[54,178,179],{"class":140}," ValueError",[54,181,182],{"class":95}," as",[54,184,185],{"class":99}," e:\n",[54,187,189,192,195,198],{"class":56,"line":188},7,[54,190,191],{"class":140},"    print",[54,193,194],{"class":99},"(",[54,196,197],{"class":64},"\"ValueError:\"",[54,199,200],{"class":99},", e)\n",[54,202,204],{"class":56,"line":203},8,[54,205,113],{"emptyLinePlaceholder":112},[54,207,209,212,214,217,219,222,225,227,230],{"class":56,"line":208},9,[54,210,211],{"class":99},"converted ",[54,213,122],{"class":95},[54,215,216],{"class":99}," pd.to_numeric(df[",[54,218,162],{"class":64},[54,220,221],{"class":99},"], ",[54,223,224],{"class":134},"errors",[54,226,122],{"class":95},[54,228,229],{"class":64},"\"coerce\"",[54,231,144],{"class":99},[54,233,235,238,240,243,246,248,250],{"class":56,"line":234},10,[54,236,237],{"class":99},"bad ",[54,239,122],{"class":95},[54,241,242],{"class":99}," df.loc[converted.isna(), [",[54,244,245],{"class":64},"\"Invoice\"",[54,247,131],{"class":99},[54,249,162],{"class":64},[54,251,252],{"class":99},"]]\n",[54,254,256,259,261,264,267,271,274,277,280,283,285,287,290,292,295],{"class":56,"line":255},11,[54,257,258],{"class":140},"print",[54,260,194],{"class":99},[54,262,263],{"class":95},"f",[54,265,266],{"class":64},"\"",[54,268,270],{"class":269},"sSjpA","{",[54,272,273],{"class":140},"len",[54,275,276],{"class":99},"(bad)",[54,278,279],{"class":269},"}",[54,281,282],{"class":64}," of ",[54,284,270],{"class":269},[54,286,273],{"class":140},[54,288,289],{"class":99},"(df)",[54,291,279],{"class":269},[54,293,294],{"class":64}," values fail:\"",[54,296,144],{"class":99},[54,298,300,302,305,308,310,313,315,318,320,323,326,328,330,333,336,338,340],{"class":56,"line":299},12,[54,301,258],{"class":140},[54,303,304],{"class":99},"(bad.assign(",[54,306,307],{"class":134},"repr",[54,309,122],{"class":95},[54,311,312],{"class":99},"bad[",[54,314,162],{"class":64},[54,316,317],{"class":99},"].map(",[54,319,307],{"class":140},[54,321,322],{"class":99},")).drop(",[54,324,325],{"class":134},"columns",[54,327,122],{"class":95},[54,329,162],{"class":64},[54,331,332],{"class":99},").to_string(",[54,334,335],{"class":134},"index",[54,337,122],{"class":95},[54,339,141],{"class":140},[54,341,342],{"class":99},"))\n",[10,344,345,347,348,351,352,355,356,359,360,363,364,366,367,369,370,373,374,377,378,381,382,385,386,388],{},[13,346,19],{}," reports the first failure only. Eleven of the fifteen values fail; the other four are already numbers, or text that ",[13,349,350],{},"to_numeric"," can read as it stands — ",[13,353,354],{},"' 310 '"," with its surrounding spaces and ",[13,357,358],{},"'3.2e3'"," in scientific notation. Comparing with ",[13,361,362],{},"pd.to_numeric(..., errors=\"coerce\")"," lists them all — every value that comes back as ",[13,365,27],{}," while the original was not empty. Printing the ",[13,368,307],{}," of each value matters, because it shows characters that are invisible in normal output: ",[13,371,372],{},"'2\\xa0500'"," contains a non-breaking space, and ",[13,375,376],{},"'−12.75'"," starts with the Unicode minus sign ",[13,379,380],{},"−"," rather than an ASCII hyphen, which looks identical on screen. ",[13,383,384],{},"keep_default_na=False"," stops pandas from quietly turning \"N\u002FA\" into ",[13,387,27],{}," on reading, so placeholder text is visible as text — otherwise it would never appear in the list.",[40,390,392],{"id":391},"step-2-group-the-failures-by-cause","Step 2 — Group the failures by cause",[45,394,396],{"className":86,"code":395,"language":88,"meta":50,"style":50},"import re\n\ndef cause(v):\n    s = str(v)\n    if s.strip().upper() in {\"N\u002FA\", \"NA\", \"TBC\", \"-\", \"\"}:\n        return \"placeholder\"\n    if \"\\xa0\" in s or \" \" in s:\n        return \"non-breaking space\"\n    if \"−\" in s:\n        return \"unicode minus\"\n    if re.fullmatch(r\"\\s*\\(.*\\)\\s*\", s):\n        return \"accounting negative\"\n    if s.strip().endswith(\"%\"):\n        return \"percentage\"\n    if re.search(r\"[€$£]\", s):\n        return \"currency symbol\"\n    if re.fullmatch(r\"\\s*-?\\d{1,3}(\\.\\d{3})+,\\d+\\s*\", s):\n        return \"decimal comma\"\n    if \",\" in s:\n        return \"thousands separator\"\n    return \"other\"\n\nprint(bad[\"Amount\"].map(cause).value_counts().to_string())\n",[13,397,398,405,409,421,434,474,482,511,518,529,536,574,581,595,603,628,636,694,702,714,722,731,736],{"__ignoreMap":50},[54,399,400,402],{"class":56,"line":57},[54,401,96],{"class":95},[54,403,404],{"class":99}," re\n",[54,406,407],{"class":56,"line":109},[54,408,113],{"emptyLinePlaceholder":112},[54,410,411,414,418],{"class":56,"line":116},[54,412,413],{"class":95},"def",[54,415,417],{"class":416},"s_Opv"," cause",[54,419,420],{"class":99},"(v):\n",[54,422,423,426,428,431],{"class":56,"line":147},[54,424,425],{"class":99},"    s ",[54,427,122],{"class":95},[54,429,430],{"class":140}," str",[54,432,433],{"class":99},"(v)\n",[54,435,436,439,442,445,448,451,453,456,458,461,463,466,468,471],{"class":56,"line":156},[54,437,438],{"class":95},"    if",[54,440,441],{"class":99}," s.strip().upper() ",[54,443,444],{"class":95},"in",[54,446,447],{"class":99}," {",[54,449,450],{"class":64},"\"N\u002FA\"",[54,452,131],{"class":99},[54,454,455],{"class":64},"\"NA\"",[54,457,131],{"class":99},[54,459,460],{"class":64},"\"TBC\"",[54,462,131],{"class":99},[54,464,465],{"class":64},"\"-\"",[54,467,131],{"class":99},[54,469,470],{"class":64},"\"\"",[54,472,473],{"class":99},"}:\n",[54,475,476,479],{"class":56,"line":173},[54,477,478],{"class":95},"        return",[54,480,481],{"class":64}," \"placeholder\"\n",[54,483,484,486,489,492,494,497,500,503,506,508],{"class":56,"line":188},[54,485,438],{"class":95},[54,487,488],{"class":64}," \"",[54,490,491],{"class":269},"\\xa0",[54,493,266],{"class":64},[54,495,496],{"class":95}," in",[54,498,499],{"class":99}," s ",[54,501,502],{"class":95},"or",[54,504,505],{"class":64}," \" \"",[54,507,496],{"class":95},[54,509,510],{"class":99}," s:\n",[54,512,513,515],{"class":56,"line":203},[54,514,478],{"class":95},[54,516,517],{"class":64}," \"non-breaking space\"\n",[54,519,520,522,525,527],{"class":56,"line":208},[54,521,438],{"class":95},[54,523,524],{"class":64}," \"−\"",[54,526,496],{"class":95},[54,528,510],{"class":99},[54,530,531,533],{"class":56,"line":234},[54,532,478],{"class":95},[54,534,535],{"class":64}," \"unicode minus\"\n",[54,537,538,540,543,546,548,551,554,558,560,562,565,567,569,571],{"class":56,"line":255},[54,539,438],{"class":95},[54,541,542],{"class":99}," re.fullmatch(",[54,544,545],{"class":95},"r",[54,547,266],{"class":64},[54,549,550],{"class":140},"\\s",[54,552,553],{"class":95},"*",[54,555,557],{"class":556},"s_b0D","\\(",[54,559,38],{"class":140},[54,561,553],{"class":95},[54,563,564],{"class":556},"\\)",[54,566,550],{"class":140},[54,568,553],{"class":95},[54,570,266],{"class":64},[54,572,573],{"class":99},", s):\n",[54,575,576,578],{"class":56,"line":299},[54,577,478],{"class":95},[54,579,580],{"class":64}," \"accounting negative\"\n",[54,582,584,586,589,592],{"class":56,"line":583},13,[54,585,438],{"class":95},[54,587,588],{"class":99}," s.strip().endswith(",[54,590,591],{"class":64},"\"%\"",[54,593,594],{"class":99},"):\n",[54,596,598,600],{"class":56,"line":597},14,[54,599,478],{"class":95},[54,601,602],{"class":64}," \"percentage\"\n",[54,604,606,608,611,613,615,618,621,624,626],{"class":56,"line":605},15,[54,607,438],{"class":95},[54,609,610],{"class":99}," re.search(",[54,612,545],{"class":95},[54,614,266],{"class":64},[54,616,617],{"class":140},"[",[54,619,620],{"class":269},"€$£",[54,622,623],{"class":140},"]",[54,625,266],{"class":64},[54,627,573],{"class":99},[54,629,631,633],{"class":56,"line":630},16,[54,632,478],{"class":95},[54,634,635],{"class":64}," \"currency symbol\"\n",[54,637,639,641,643,645,647,649,651,654,657,660,663,665,668,670,673,676,679,682,684,686,688,690,692],{"class":56,"line":638},17,[54,640,438],{"class":95},[54,642,542],{"class":99},[54,644,545],{"class":95},[54,646,266],{"class":64},[54,648,550],{"class":140},[54,650,553],{"class":95},[54,652,653],{"class":64},"-",[54,655,656],{"class":95},"?",[54,658,659],{"class":140},"\\d",[54,661,662],{"class":95},"{1,3}",[54,664,194],{"class":140},[54,666,667],{"class":556},"\\.",[54,669,659],{"class":140},[54,671,672],{"class":95},"{3}",[54,674,675],{"class":140},")",[54,677,678],{"class":95},"+",[54,680,681],{"class":64},",",[54,683,659],{"class":140},[54,685,678],{"class":95},[54,687,550],{"class":140},[54,689,553],{"class":95},[54,691,266],{"class":64},[54,693,573],{"class":99},[54,695,697,699],{"class":56,"line":696},18,[54,698,478],{"class":95},[54,700,701],{"class":64}," \"decimal comma\"\n",[54,703,705,707,710,712],{"class":56,"line":704},19,[54,706,438],{"class":95},[54,708,709],{"class":64}," \",\"",[54,711,496],{"class":95},[54,713,510],{"class":99},[54,715,717,719],{"class":56,"line":716},20,[54,718,478],{"class":95},[54,720,721],{"class":64}," \"thousands separator\"\n",[54,723,725,728],{"class":56,"line":724},21,[54,726,727],{"class":95},"    return",[54,729,730],{"class":64}," \"other\"\n",[54,732,734],{"class":56,"line":733},22,[54,735,113],{"emptyLinePlaceholder":112},[54,737,739,741,744,746],{"class":56,"line":738},23,[54,740,258],{"class":140},[54,742,743],{"class":99},"(bad[",[54,745,162],{"class":64},[54,747,748],{"class":99},"].map(cause).value_counts().to_string())\n",[10,750,751,752,755,756,759],{},"Most failures fall into a handful of causes, and each has its own correct fix — which is why a single ",[13,753,754],{},"str.replace(\",\", \"\")"," is dangerous: applied to ",[13,757,758],{},"1.234,56",", a European-format amount, it produces 1.23456. Classifying first shows what the column actually contains; on real data, print a few examples of each cause before deciding how to treat it.",[761,762,770,771,770,775,770,779,770,787,770,795,770,802,770,809,770,812,770,816,770,821,770,827,770,829,770,834,770,836,770,839,770,842,770,846,770,848,770,852,770,854,770,857,770,860,770,864,770,866,770,870,770,872,770,875,770,878,770,882,770,884,770,888,770,890,770,893,770,896,770,900,770,902,770,906,770,908,770,911,770,914,770,918,770,920,770,923,770,925,770,928,770,931,770,935,770,937,770,941,770,943],"svg",{"viewBox":763,"role":764,"ariaLabelledBy":765,"xmlns":768,"style":769},"4 0 752 310","img",[766,767],"sf-causes-t","sf-causes-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[772,773,774],"title",{"id":766},"Why values fail to convert, and the fix for each",[776,777,778],"desc",{"id":767},"Thousands separators are removed. Currency symbols are stripped. Percentages are divided by 100. Accounting negatives in parentheses become negative numbers. Non-breaking spaces and Unicode minus signs are normalised. European decimal commas swap separators. Placeholder text becomes a true missing value.",[780,781],"rect",{"x":782,"y":783,"width":784,"height":785,"fill":786},"4","0","752","310","#ffffff",[780,788],{"x":789,"y":790,"width":791,"height":792,"rx":783,"fill":786,"stroke":793,"style":794},"20.0","16.0","170.7","40.0","var(--line,#cdd5e6)","stroke-width:1px",[780,796],{"x":797,"y":790,"width":798,"height":792,"rx":783,"fill":799,"stroke":800,"style":801},"190.7","274.7","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.2px",[803,804,808],"text",{"x":805,"y":806,"style":807},"328.0","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","example",[780,810],{"x":811,"y":790,"width":798,"height":792,"rx":783,"fill":799,"stroke":800,"style":801},"465.3",[803,813,815],{"x":814,"y":806,"style":807},"602.7","fix",[780,817],{"x":789,"y":818,"width":791,"height":819,"rx":783,"fill":820,"stroke":793,"style":794},"56.0","34.0","#e7ebef",[803,822,826],{"x":823,"y":824,"style":825},"32.0","78.0","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start","thousands separator",[780,828],{"x":797,"y":818,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,830,833],{"x":805,"y":831,"style":832},"77.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","1,234.50",[780,835],{"x":811,"y":818,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,837,838],{"x":814,"y":831,"style":832},"remove ,",[780,840],{"x":789,"y":841,"width":791,"height":819,"rx":783,"fill":820,"stroke":793,"style":794},"90.0",[803,843,845],{"x":823,"y":844,"style":825},"112.0","currency symbol",[780,847],{"x":797,"y":841,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,849,851],{"x":805,"y":850,"style":832},"111.0","€ 980.00",[780,853],{"x":811,"y":841,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,855,856],{"x":814,"y":850,"style":832},"strip symbol",[780,858],{"x":789,"y":859,"width":791,"height":819,"rx":783,"fill":820,"stroke":793,"style":794},"124.0",[803,861,863],{"x":823,"y":862,"style":825},"146.0","percentage",[780,865],{"x":797,"y":859,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,867,869],{"x":805,"y":868,"style":832},"145.0","12.5%",[780,871],{"x":811,"y":859,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,873,874],{"x":814,"y":868,"style":832},"÷ 100",[780,876],{"x":789,"y":877,"width":791,"height":819,"rx":783,"fill":820,"stroke":793,"style":794},"158.0",[803,879,881],{"x":823,"y":880,"style":825},"180.0","accounting negative",[780,883],{"x":797,"y":877,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,885,887],{"x":805,"y":886,"style":832},"179.0","(45.00)",[780,889],{"x":811,"y":877,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,891,892],{"x":814,"y":886,"style":832},"−45.00",[780,894],{"x":789,"y":895,"width":791,"height":819,"rx":783,"fill":820,"stroke":793,"style":794},"192.0",[803,897,899],{"x":823,"y":898,"style":825},"214.0","NBSP \u002F Unicode minus",[780,901],{"x":797,"y":895,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,903,905],{"x":805,"y":904,"style":832},"213.0","2 500, −12.75",[780,907],{"x":811,"y":895,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,909,910],{"x":814,"y":904,"style":832},"normalise characters",[780,912],{"x":789,"y":913,"width":791,"height":819,"rx":783,"fill":820,"stroke":793,"style":794},"226.0",[803,915,917],{"x":823,"y":916,"style":825},"248.0","decimal comma",[780,919],{"x":797,"y":913,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,921,758],{"x":805,"y":922,"style":832},"247.0",[780,924],{"x":811,"y":913,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,926,927],{"x":814,"y":922,"style":832},"swap separators",[780,929],{"x":789,"y":930,"width":791,"height":819,"rx":783,"fill":820,"stroke":793,"style":794},"260.0",[803,932,934],{"x":823,"y":933,"style":825},"282.0","placeholder",[780,936],{"x":797,"y":930,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,938,940],{"x":805,"y":939,"style":832},"281.0","N\u002FA, TBC, -",[780,942],{"x":811,"y":930,"width":798,"height":819,"rx":783,"fill":786,"stroke":793,"style":794},[803,944,945],{"x":814,"y":939,"style":832},"missing value",[40,947,949],{"id":948},"step-3-clean-deliberately-and-report-the-rest","Step 3 — Clean deliberately, and report the rest",[45,951,953],{"className":86,"code":952,"language":88,"meta":50,"style":50},"def to_number(v):\n    if isinstance(v, (int, float)):\n        return float(v)\n    s = str(v).replace(\"\\xa0\", \"\").replace(\" \", \"\").replace(\"−\", \"-\").strip()\n    if s.upper() in {\"N\u002FA\", \"NA\", \"TBC\", \"-\", \"\"}:\n        return None\n    negative = s.startswith(\"(\") and s.endswith(\")\")\n    s = s.strip(\"()\").replace(\"€\", \"\").replace(\"$\", \"\").replace(\"£\", \"\").strip()\n    percent = s.endswith(\"%\")\n    s = s.rstrip(\"%\").strip()\n    if re.fullmatch(r\"-?\\d{1,3}(\\.\\d{3})+,\\d+\", s):        # 1.234,56  ->  1234.56\n        s = s.replace(\".\", \"\").replace(\",\", \".\")\n    s = s.replace(\",\", \"\").replace(\" \", \"\")\n    try:\n        x = float(s)\n    except ValueError:\n        return \"unparsed\"\n    x = -x if negative else x\n    return x \u002F 100 if percent else x\n\ncleaned = df[\"Amount\"].map(to_number)\nunparsed = df.loc[cleaned.eq(\"unparsed\"), \"Invoice\"].tolist()\ndf[\"Amount (number)\"] = pd.to_numeric(cleaned.where(cleaned.ne(\"unparsed\")), errors=\"coerce\")\nprint(df.assign(original=df[\"Amount\"].map(repr))[[\"Invoice\", \"original\", \"Amount (number)\"]].to_string(index=False))\nprint(\"placeholders -> missing:\", int(df[\"Amount (number)\"].isna().sum()), \"| still unparsed:\", unparsed or \"none\")\n",[13,954,955,964,984,993,1036,1067,1074,1101,1142,1155,1168,1212,1240,1265,1272,1284,1293,1300,1325,1348,1352,1367,1388,1417,1463],{"__ignoreMap":50},[54,956,957,959,962],{"class":56,"line":57},[54,958,413],{"class":95},[54,960,961],{"class":416}," to_number",[54,963,420],{"class":99},[54,965,966,968,971,974,977,979,981],{"class":56,"line":109},[54,967,438],{"class":95},[54,969,970],{"class":140}," isinstance",[54,972,973],{"class":99},"(v, (",[54,975,976],{"class":140},"int",[54,978,131],{"class":99},[54,980,168],{"class":140},[54,982,983],{"class":99},")):\n",[54,985,986,988,991],{"class":56,"line":116},[54,987,478],{"class":95},[54,989,990],{"class":140}," float",[54,992,433],{"class":99},[54,994,995,997,999,1001,1004,1006,1008,1010,1012,1014,1017,1020,1022,1024,1026,1029,1031,1033],{"class":56,"line":147},[54,996,425],{"class":99},[54,998,122],{"class":95},[54,1000,430],{"class":140},[54,1002,1003],{"class":99},"(v).replace(",[54,1005,266],{"class":64},[54,1007,491],{"class":269},[54,1009,266],{"class":64},[54,1011,131],{"class":99},[54,1013,470],{"class":64},[54,1015,1016],{"class":99},").replace(",[54,1018,1019],{"class":64},"\" \"",[54,1021,131],{"class":99},[54,1023,470],{"class":64},[54,1025,1016],{"class":99},[54,1027,1028],{"class":64},"\"−\"",[54,1030,131],{"class":99},[54,1032,465],{"class":64},[54,1034,1035],{"class":99},").strip()\n",[54,1037,1038,1040,1043,1045,1047,1049,1051,1053,1055,1057,1059,1061,1063,1065],{"class":56,"line":156},[54,1039,438],{"class":95},[54,1041,1042],{"class":99}," s.upper() ",[54,1044,444],{"class":95},[54,1046,447],{"class":99},[54,1048,450],{"class":64},[54,1050,131],{"class":99},[54,1052,455],{"class":64},[54,1054,131],{"class":99},[54,1056,460],{"class":64},[54,1058,131],{"class":99},[54,1060,465],{"class":64},[54,1062,131],{"class":99},[54,1064,470],{"class":64},[54,1066,473],{"class":99},[54,1068,1069,1071],{"class":56,"line":173},[54,1070,478],{"class":95},[54,1072,1073],{"class":140}," None\n",[54,1075,1076,1079,1081,1084,1087,1090,1093,1096,1099],{"class":56,"line":188},[54,1077,1078],{"class":99},"    negative ",[54,1080,122],{"class":95},[54,1082,1083],{"class":99}," s.startswith(",[54,1085,1086],{"class":64},"\"(\"",[54,1088,1089],{"class":99},") ",[54,1091,1092],{"class":95},"and",[54,1094,1095],{"class":99}," s.endswith(",[54,1097,1098],{"class":64},"\")\"",[54,1100,144],{"class":99},[54,1102,1103,1105,1107,1110,1113,1115,1118,1120,1122,1124,1127,1129,1131,1133,1136,1138,1140],{"class":56,"line":203},[54,1104,425],{"class":99},[54,1106,122],{"class":95},[54,1108,1109],{"class":99}," s.strip(",[54,1111,1112],{"class":64},"\"()\"",[54,1114,1016],{"class":99},[54,1116,1117],{"class":64},"\"€\"",[54,1119,131],{"class":99},[54,1121,470],{"class":64},[54,1123,1016],{"class":99},[54,1125,1126],{"class":64},"\"$\"",[54,1128,131],{"class":99},[54,1130,470],{"class":64},[54,1132,1016],{"class":99},[54,1134,1135],{"class":64},"\"£\"",[54,1137,131],{"class":99},[54,1139,470],{"class":64},[54,1141,1035],{"class":99},[54,1143,1144,1147,1149,1151,1153],{"class":56,"line":208},[54,1145,1146],{"class":99},"    percent ",[54,1148,122],{"class":95},[54,1150,1095],{"class":99},[54,1152,591],{"class":64},[54,1154,144],{"class":99},[54,1156,1157,1159,1161,1164,1166],{"class":56,"line":234},[54,1158,425],{"class":99},[54,1160,122],{"class":95},[54,1162,1163],{"class":99}," s.rstrip(",[54,1165,591],{"class":64},[54,1167,1035],{"class":99},[54,1169,1170,1172,1174,1176,1179,1181,1183,1185,1187,1189,1191,1193,1195,1197,1199,1201,1203,1205,1208],{"class":56,"line":255},[54,1171,438],{"class":95},[54,1173,542],{"class":99},[54,1175,545],{"class":95},[54,1177,1178],{"class":64},"\"-",[54,1180,656],{"class":95},[54,1182,659],{"class":140},[54,1184,662],{"class":95},[54,1186,194],{"class":140},[54,1188,667],{"class":556},[54,1190,659],{"class":140},[54,1192,672],{"class":95},[54,1194,675],{"class":140},[54,1196,678],{"class":95},[54,1198,681],{"class":64},[54,1200,659],{"class":140},[54,1202,678],{"class":95},[54,1204,266],{"class":64},[54,1206,1207],{"class":99},", s):        ",[54,1209,1211],{"class":1210},"s-wDw","# 1.234,56  ->  1234.56\n",[54,1213,1214,1217,1219,1222,1225,1227,1229,1231,1234,1236,1238],{"class":56,"line":299},[54,1215,1216],{"class":99},"        s ",[54,1218,122],{"class":95},[54,1220,1221],{"class":99}," s.replace(",[54,1223,1224],{"class":64},"\".\"",[54,1226,131],{"class":99},[54,1228,470],{"class":64},[54,1230,1016],{"class":99},[54,1232,1233],{"class":64},"\",\"",[54,1235,131],{"class":99},[54,1237,1224],{"class":64},[54,1239,144],{"class":99},[54,1241,1242,1244,1246,1248,1250,1252,1254,1256,1259,1261,1263],{"class":56,"line":583},[54,1243,425],{"class":99},[54,1245,122],{"class":95},[54,1247,1221],{"class":99},[54,1249,1233],{"class":64},[54,1251,131],{"class":99},[54,1253,470],{"class":64},[54,1255,1016],{"class":99},[54,1257,1258],{"class":64},"\" \"",[54,1260,131],{"class":99},[54,1262,470],{"class":64},[54,1264,144],{"class":99},[54,1266,1267,1270],{"class":56,"line":597},[54,1268,1269],{"class":95},"    try",[54,1271,153],{"class":99},[54,1273,1274,1277,1279,1281],{"class":56,"line":605},[54,1275,1276],{"class":99},"        x ",[54,1278,122],{"class":95},[54,1280,990],{"class":140},[54,1282,1283],{"class":99},"(s)\n",[54,1285,1286,1289,1291],{"class":56,"line":630},[54,1287,1288],{"class":95},"    except",[54,1290,179],{"class":140},[54,1292,153],{"class":99},[54,1294,1295,1297],{"class":56,"line":638},[54,1296,478],{"class":95},[54,1298,1299],{"class":64}," \"unparsed\"\n",[54,1301,1302,1305,1307,1310,1313,1316,1319,1322],{"class":56,"line":696},[54,1303,1304],{"class":99},"    x ",[54,1306,122],{"class":95},[54,1308,1309],{"class":95}," -",[54,1311,1312],{"class":99},"x ",[54,1314,1315],{"class":95},"if",[54,1317,1318],{"class":99}," negative ",[54,1320,1321],{"class":95},"else",[54,1323,1324],{"class":99}," x\n",[54,1326,1327,1329,1332,1335,1338,1341,1344,1346],{"class":56,"line":704},[54,1328,727],{"class":95},[54,1330,1331],{"class":99}," x ",[54,1333,1334],{"class":95},"\u002F",[54,1336,1337],{"class":140}," 100",[54,1339,1340],{"class":95}," if",[54,1342,1343],{"class":99}," percent ",[54,1345,1321],{"class":95},[54,1347,1324],{"class":99},[54,1349,1350],{"class":56,"line":716},[54,1351,113],{"emptyLinePlaceholder":112},[54,1353,1354,1357,1359,1362,1364],{"class":56,"line":724},[54,1355,1356],{"class":99},"cleaned ",[54,1358,122],{"class":95},[54,1360,1361],{"class":99}," df[",[54,1363,162],{"class":64},[54,1365,1366],{"class":99},"].map(to_number)\n",[54,1368,1369,1372,1374,1377,1380,1383,1385],{"class":56,"line":733},[54,1370,1371],{"class":99},"unparsed ",[54,1373,122],{"class":95},[54,1375,1376],{"class":99}," df.loc[cleaned.eq(",[54,1378,1379],{"class":64},"\"unparsed\"",[54,1381,1382],{"class":99},"), ",[54,1384,245],{"class":64},[54,1386,1387],{"class":99},"].tolist()\n",[54,1389,1390,1393,1396,1399,1401,1404,1406,1409,1411,1413,1415],{"class":56,"line":738},[54,1391,1392],{"class":99},"df[",[54,1394,1395],{"class":64},"\"Amount (number)\"",[54,1397,1398],{"class":99},"] ",[54,1400,122],{"class":95},[54,1402,1403],{"class":99}," pd.to_numeric(cleaned.where(cleaned.ne(",[54,1405,1379],{"class":64},[54,1407,1408],{"class":99},")), ",[54,1410,224],{"class":134},[54,1412,122],{"class":95},[54,1414,229],{"class":64},[54,1416,144],{"class":99},[54,1418,1420,1422,1425,1428,1430,1432,1434,1436,1438,1441,1443,1445,1448,1450,1452,1455,1457,1459,1461],{"class":56,"line":1419},24,[54,1421,258],{"class":140},[54,1423,1424],{"class":99},"(df.assign(",[54,1426,1427],{"class":134},"original",[54,1429,122],{"class":95},[54,1431,1392],{"class":99},[54,1433,162],{"class":64},[54,1435,317],{"class":99},[54,1437,307],{"class":140},[54,1439,1440],{"class":99},"))[[",[54,1442,245],{"class":64},[54,1444,131],{"class":99},[54,1446,1447],{"class":64},"\"original\"",[54,1449,131],{"class":99},[54,1451,1395],{"class":64},[54,1453,1454],{"class":99},"]].to_string(",[54,1456,335],{"class":134},[54,1458,122],{"class":95},[54,1460,141],{"class":140},[54,1462,342],{"class":99},[54,1464,1466,1468,1470,1473,1475,1477,1480,1482,1485,1488,1491,1493,1496],{"class":56,"line":1465},25,[54,1467,258],{"class":140},[54,1469,194],{"class":99},[54,1471,1472],{"class":64},"\"placeholders -> missing:\"",[54,1474,131],{"class":99},[54,1476,976],{"class":140},[54,1478,1479],{"class":99},"(df[",[54,1481,1395],{"class":64},[54,1483,1484],{"class":99},"].isna().sum()), ",[54,1486,1487],{"class":64},"\"| still unparsed:\"",[54,1489,1490],{"class":99},", unparsed ",[54,1492,502],{"class":95},[54,1494,1495],{"class":64}," \"none\"",[54,1497,144],{"class":99},[10,1499,1500,1501,1503,1504,1507,1508,1511,1512,1514,1515,1517],{},"Each rule is explicit and in a deliberate order: invisible characters are normalised first, so the later rules see plain text; placeholders become true missing values; parentheses and currency symbols are stripped, remembering the sign; the European pattern — dots for thousands and a comma for decimals — is recognised before ordinary commas are removed, so ",[13,1502,758],{}," becomes 1,234.56 rather than 1.23456; percentages are divided by 100. Scientific notation such as ",[13,1505,1506],{},"3.2e3"," needs no special handling, because ",[13,1509,1510],{},"float()"," understands it. Anything the rules do not recognise is marked ",[13,1513,1379],{}," rather than silently turned into ",[13,1516,27],{},", so a new format appearing next month shows up in the report instead of becoming a missing amount. Here every value converts, and the three placeholders become missing values — which is different from zero and should stay that way.",[761,1519,770,1524,770,1527,770,1530,770,1533,770,1539,770,1550,770,1556,770,1560,770,1564,770,1569,770,1574,770,1579,770,1586,770,1591,770,1594,770,1597,770,1601,770,1604,770,1607,770,1614,770,1620,770,1624,770,1628,770,1631,770,1635,770,1638,770,1643,770,1650,770,1655,770,1659,770,1662,770,1666,770,1669,770,1672,770,1678,770,1682,770,1685,770,1688],{"viewBox":1520,"role":764,"ariaLabelledBy":1521,"xmlns":768,"style":769},"4 0 752 160",[1522,1523],"sf-flow-t","sf-flow-d",[772,1525,1526],{"id":1522},"Converting a messy amount column",[776,1528,1529],{"id":1523},"Find every failing value with to_numeric and coerce, print their repr to see hidden characters, group them by cause, apply one explicit rule per cause in a fixed order, and report any value that no rule handles instead of turning it into NaN.",[780,1531],{"x":782,"y":783,"width":784,"height":1532,"fill":786},"160",[780,1534],{"x":789,"y":790,"width":1535,"height":1536,"rx":1537,"fill":820,"stroke":793,"style":1538},"115.2","128.0","12","stroke-width:2px",[1540,1541,1543],"g",{"transform":1542},"translate(65.6,37.8) scale(1.000)",[1544,1545],"path",{"d":1546,"fill":1547,"stroke":1548,"style":1549},"M11 4a7 7 0 1 0 .01 0z M16 16l5 5","none","var(--text,#172033)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[803,1551,1555],{"x":1552,"y":1553,"style":1554},"77.6","84.2","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Find failures",[803,1557,1559],{"x":1552,"y":1558,"style":832},"103.8","to_numeric(coerce)",[803,1561,1563],{"x":1552,"y":1562,"style":832},"121.2","vs original",[56,1565],{"x1":1566,"y1":1567,"x2":1568,"y2":1567,"stroke":800,"style":1538},"140.2","80.0","162.2",[1570,1571],"polygon",{"points":1572,"fill":1573},"166.2,80.0 157.2,85.0 157.2,75.0","#5b5cf0",[780,1575],{"x":1576,"y":790,"width":1535,"height":1536,"rx":1537,"fill":1577,"stroke":1578,"style":1538},"171.2","#fdefd8","var(--gold,#b4740a)",[1540,1580,1582],{"transform":1581},"translate(216.8,37.8) scale(1.000)",[1544,1583],{"d":1584,"fill":1547,"stroke":1585,"style":1549},"M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z M12 9a3 3 0 1 0 .01 0z","var(--gold-ink,#7a4e06)",[803,1587,1590],{"x":1588,"y":1553,"style":1589},"228.8","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Look at repr",[803,1592,1593],{"x":1588,"y":1558,"style":832},"\\xa0, \\u2212",[803,1595,1596],{"x":1588,"y":1562,"style":832},"visible",[56,1598],{"x1":1599,"y1":1567,"x2":1600,"y2":1567,"stroke":800,"style":1538},"291.4","313.4",[1570,1602],{"points":1603,"fill":1573},"317.4,80.0 308.4,85.0 308.4,75.0",[780,1605],{"x":1606,"y":790,"width":1535,"height":1536,"rx":1537,"fill":799,"stroke":800,"style":1538},"322.4",[1540,1608,1610],{"transform":1609},"translate(368.0,29.0) scale(1.000)",[1544,1611],{"d":1612,"fill":1547,"stroke":1613,"style":1549},"M12 3l9 5-9 5-9-5z M3 13l9 5 9-5 M3 17l9 5 9-5","var(--brand-strong,#4338ca)",[803,1615,1619],{"x":1616,"y":1617,"style":1618},"380.0","75.5","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Group by",[803,1621,1623],{"x":1616,"y":1622,"style":1618},"93.0","cause",[803,1625,1627],{"x":1616,"y":1626,"style":832},"112.5","one fix per",[803,1629,1623],{"x":1616,"y":1630,"style":832},"130.0",[56,1632],{"x1":1633,"y1":1567,"x2":1634,"y2":1567,"stroke":800,"style":1538},"442.6","464.6",[1570,1636],{"points":1637,"fill":1573},"468.6,80.0 459.6,85.0 459.6,75.0",[780,1639],{"x":1640,"y":790,"width":1535,"height":1536,"rx":1537,"fill":1641,"stroke":1642,"style":1538},"473.6","#d9f4f1","var(--teal,#0f9488)",[1540,1644,1646],{"transform":1645},"translate(519.2,37.8) scale(1.000)",[1544,1647],{"d":1648,"fill":1547,"stroke":1649,"style":1549},"M3 5h18l-7 8v6l-4 2v-8z","var(--teal-ink,#0b6157)",[803,1651,1654],{"x":1652,"y":1553,"style":1653},"531.2","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Clean in",[803,1656,1658],{"x":1652,"y":1657,"style":1653},"101.8","order",[803,1660,1661],{"x":1652,"y":1562,"style":832},"characters first",[56,1663],{"x1":1664,"y1":1567,"x2":1665,"y2":1567,"stroke":800,"style":1538},"593.8","615.8",[1570,1667],{"points":1668,"fill":1573},"619.8,80.0 610.8,85.0 610.8,75.0",[780,1670],{"x":1671,"y":790,"width":1535,"height":1536,"rx":1537,"fill":1577,"stroke":1578,"style":1538},"624.8",[1540,1673,1675],{"transform":1674},"translate(670.4,29.0) scale(1.000)",[1544,1676],{"d":1677,"fill":1547,"stroke":1585,"style":1549},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4",[803,1679,1681],{"x":1680,"y":1617,"style":1589},"682.4","Report",[803,1683,1684],{"x":1680,"y":1622,"style":1589},"leftovers",[803,1686,1687],{"x":1680,"y":1626,"style":832},"never silently",[803,1689,27],{"x":1680,"y":1630,"style":832},[761,1691,770,1697,770,1700,770,1703,770,1708,770,1712,770,1716,770,1722,770,1726,770,1731,770,1733,770,1737,770,1740,770,1743,770,1745,770,1749,770,1752,770,1756,770,1758,770,1761,770,1764,770,1767,770,1769,770,1772,770,1775,770,1779,770,1781,770,1784,770,1787,770,1791,770,1793,770,1796,770,1799,770,1803,770,1806,770,1808,770,1811,770,1813,770,1816,770,1818,770,1820,770,1822,770,1825,770,1827,770,1829,770,1831,770,1834,770,1836,770,1838,770,1840,770,1843,770,1845,770,1847,770,1849,770,1852,770,1854,770,1856,770,1859,770,1863,770,1869,770,1873,770,1878,770,1881,770,1888],{"viewBox":1692,"role":764,"ariaLabelledBy":1693,"xmlns":768,"style":1696},"128 0 504 248",[1694,1695],"sf-before-after-t","sf-before-after-d","width:100%;max-width:504px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[772,1698,1699],{"id":1694},"The Amount column before and after cleaning",[776,1701,1702],{"id":1695},"Text values such as 1,234.50, euro 980.00, 12.5 percent, 45.00 in parentheses, 2 500 with a non-breaking space and 1.234,56 become the numbers 1234.5, 980, 0.125, minus 45, 2500 and 1234.56. N\u002FA becomes a missing value.",[780,1704],{"x":1705,"y":783,"width":1706,"height":1707,"fill":786},"128","504","248",[780,1709],{"x":1710,"y":792,"width":823,"height":1711,"rx":783,"fill":820,"stroke":793,"style":794},"144.2","24.0",[780,1713],{"x":1714,"y":792,"width":1715,"height":1711,"rx":783,"fill":820,"stroke":793,"style":794},"176.2","109.5",[803,1717,1721],{"x":1718,"y":1719,"style":1720},"230.9","57.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[780,1723],{"x":1710,"y":1724,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},"64.0","28.0",[803,1727,1730],{"x":1728,"y":1729,"style":1720},"160.2","83.0","1",[780,1732],{"x":1714,"y":1724,"width":1715,"height":1725,"rx":783,"fill":786,"stroke":793,"style":794},[803,1734,1736],{"x":1718,"y":1729,"style":1735},"font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Amount (text)",[780,1738],{"x":1710,"y":1739,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},"92.0",[803,1741,1742],{"x":1728,"y":850,"style":1720},"2",[780,1744],{"x":1714,"y":1739,"width":1715,"height":1725,"rx":783,"fill":786,"stroke":793,"style":794},[803,1746,1748],{"x":1718,"y":850,"style":1747},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","'1,234.50'",[780,1750],{"x":1710,"y":1751,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},"120.0",[803,1753,1755],{"x":1728,"y":1754,"style":1720},"139.0","3",[780,1757],{"x":1714,"y":1751,"width":1715,"height":1725,"rx":783,"fill":786,"stroke":793,"style":794},[803,1759,1760],{"x":1718,"y":1754,"style":1747},"'(45.00)'",[780,1762],{"x":1710,"y":1763,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},"148.0",[803,1765,782],{"x":1728,"y":1766,"style":1720},"167.0",[780,1768],{"x":1714,"y":1763,"width":1715,"height":1725,"rx":783,"fill":786,"stroke":793,"style":794},[803,1770,1771],{"x":1718,"y":1766,"style":1747},"'1.234,56'",[780,1773],{"x":1710,"y":1774,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},"176.0",[803,1776,1778],{"x":1728,"y":1777,"style":1720},"195.0","5",[780,1780],{"x":1714,"y":1774,"width":1715,"height":1725,"rx":783,"fill":786,"stroke":793,"style":794},[803,1782,1783],{"x":1718,"y":1777,"style":1747},"'12.5%'",[780,1785],{"x":1710,"y":1786,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},"204.0",[803,1788,1790],{"x":1728,"y":1789,"style":1720},"223.0","6",[780,1792],{"x":1714,"y":1786,"width":1715,"height":1725,"rx":783,"fill":786,"stroke":793,"style":794},[803,1794,1795],{"x":1718,"y":1789,"style":1747},"'N\u002FA'",[780,1797],{"x":1798,"y":792,"width":823,"height":1711,"rx":783,"fill":820,"stroke":793,"style":794},"450.6",[780,1800],{"x":1801,"y":792,"width":1802,"height":1711,"rx":783,"fill":820,"stroke":793,"style":794},"482.6","133.2",[803,1804,1721],{"x":1805,"y":1719,"style":1720},"549.2",[780,1807],{"x":1798,"y":1724,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},[803,1809,1730],{"x":1810,"y":1729,"style":1720},"466.6",[780,1812],{"x":1801,"y":1724,"width":1802,"height":1725,"rx":783,"fill":786,"stroke":793,"style":794},[803,1814,1815],{"x":1805,"y":1729,"style":1735},"Amount (number)",[780,1817],{"x":1798,"y":1739,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},[803,1819,1742],{"x":1810,"y":850,"style":1720},[780,1821],{"x":1801,"y":1739,"width":1802,"height":1725,"rx":783,"fill":786,"stroke":793,"style":794},[803,1823,1824],{"x":1805,"y":850,"style":1747},"1234.50",[780,1826],{"x":1798,"y":1751,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},[803,1828,1755],{"x":1810,"y":1754,"style":1720},[780,1830],{"x":1801,"y":1751,"width":1802,"height":1725,"rx":783,"fill":786,"stroke":793,"style":794},[803,1832,1833],{"x":1805,"y":1754,"style":1747},"-45.00",[780,1835],{"x":1798,"y":1763,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},[803,1837,782],{"x":1810,"y":1766,"style":1720},[780,1839],{"x":1801,"y":1763,"width":1802,"height":1725,"rx":783,"fill":786,"stroke":793,"style":794},[803,1841,1842],{"x":1805,"y":1766,"style":1747},"1234.56",[780,1844],{"x":1798,"y":1774,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},[803,1846,1778],{"x":1810,"y":1777,"style":1720},[780,1848],{"x":1801,"y":1774,"width":1802,"height":1725,"rx":783,"fill":786,"stroke":793,"style":794},[803,1850,1851],{"x":1805,"y":1777,"style":1747},"0.125",[780,1853],{"x":1798,"y":1786,"width":823,"height":1725,"rx":783,"fill":820,"stroke":793,"style":794},[803,1855,1790],{"x":1810,"y":1789,"style":1720},[780,1857],{"x":1801,"y":1786,"width":1802,"height":1725,"rx":783,"fill":1577,"stroke":1578,"style":1858},"stroke-width:1.5px",[803,1860,1862],{"x":1805,"y":1789,"style":1861},"font-size:12px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","(missing)",[803,1864,1868],{"x":1865,"y":1866,"style":1867},"214.9","29.0","font-size:12.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","before",[803,1870,1872],{"x":1871,"y":1866,"style":1867},"533.2","after",[56,1874],{"x1":1875,"y1":1876,"x2":1877,"y2":1876,"stroke":800,"style":1538},"295.7","136.0","436.6",[1570,1879],{"points":1880,"fill":1573},"440.6,136.0 431.6,141.0 431.6,131.0",[780,1882],{"x":1883,"y":1884,"width":1885,"height":1886,"rx":1887,"fill":786,"stroke":793,"style":801},"318.2","103.0","100.0","22.0","11",[803,1889,1893],{"x":1890,"y":1891,"style":1892},"368.1","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","to_number()",[40,1895,1897],{"id":1896},"where-these-values-come-from","Where these values come from",[10,1899,1900,1901,1904],{},"Knowing the origin of each format helps decide whether to clean it or fix it at the source. Thousands separators and currency symbols usually mean a system exported ",[76,1902,1903],{},"formatted"," values instead of raw numbers, or someone pasted from a web page or PDF. Non-breaking spaces arrive with copy and paste from web pages and from French or other locales that group digits with a narrow space. The Unicode minus sign comes from word processors and some reporting tools that \"beautify\" negative numbers. Parentheses for negatives are the accounting convention, typed by hand or exported from finance systems. Decimal commas mean the data passed through a machine set to a European locale. And \"N\u002FA\", \"TBC\" and \"-\" are people filling a required cell with a placeholder. Each of these says something about the process that produced the file, and a short note on each to the file's owner often removes the problem for good.",[40,1906,1908],{"id":1907},"keep-the-original-next-to-the-result","Keep the original next to the result",[10,1910,1911],{},"Write the cleaned values to a new column, as above, rather than overwriting the original — at least until the cleaning has been checked. Having both side by side makes review easy: sort by the original, filter to rows where the original was text, and confirm each conversion at a glance. It also leaves an audit trail when the converted figures go into a report, so a question such as \"why is invoice 7 1,234.56 and not 1.23?\" can be answered from the file itself. Once the rules have been reviewed, keep them in one function shared by every script that reads the column, and add a test with one example of each format, so a later change to the rules cannot quietly break a case that used to work. Values that remain unparsed belong in a short exception list sent back to whoever maintains the source.",[40,1913,1915],{"id":1914},"prevent-it-upstream","Prevent it upstream",[10,1917,1918,1919,1923,1924,1927,1928,1931,1932,38],{},"The cleaning function is a repair; the lasting fix is upstream. If the column comes from a form or template people fill in, restrict it with data validation so only numbers can be entered, as in ",[34,1920,1922],{"href":1921},"\u002Fadvanced-data-transformation-and-cleaning\u002Fvalidating-excel-data-with-python\u002Fadd-dropdown-data-validation-to-excel-with-openpyxl\u002F","Add Dropdown Data Validation to Excel with openpyxl",". If it comes from another system's export, ask for raw numbers rather than formatted text — most systems can do both. And if it comes from CSV, read it with the right ",[13,1925,1926],{},"thousands"," and ",[13,1929,1930],{},"decimal"," arguments, which handle the separators during parsing. The specific case of percentages stored as text is covered in ",[34,1933,1935],{"href":1934},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fconvert-percentage-strings-to-numbers-with-pandas\u002F","Convert Percentage Strings Like \"12.5%\" to Numbers with pandas",[40,1937,1939],{"id":1938},"common-pitfalls","Common pitfalls",[1941,1942,1943,1954,1963,1969,1979],"ul",{},[1944,1945,1946,1950,1951,38],"li",{},[1947,1948,1949],"strong",{},"Fixing one error at a time."," List every failing value with ",[13,1952,1953],{},"to_numeric(errors=\"coerce\")",[1944,1955,1956,1962],{},[1947,1957,1958,1961],{},[13,1959,1960],{},"errors=\"coerce\""," as the fix."," It hides good values written in unexpected formats.",[1944,1964,1965,1968],{},[1947,1966,1967],{},"Removing all commas."," It breaks European decimal commas.",[1944,1970,1971,1974,1975,1978],{},[1947,1972,1973],{},"Invisible characters."," Print ",[13,1976,1977],{},"repr()"," to see non-breaking spaces and Unicode minus signs.",[1944,1980,1981,1984],{},[1947,1982,1983],{},"Placeholders as zero."," \"N\u002FA\" is missing, not 0.",[40,1986,1988],{"id":1987},"conclusion","Conclusion",[10,1990,1991,1992,1994,1995,1997,1998,2000],{},"\"Could not convert string to float\" means the column contains text. Find every failing value at once by comparing with ",[13,1993,23],{},", look at their ",[13,1996,307],{}," to reveal hidden characters, group them by cause, and convert with explicit rules applied in order — invisible characters, placeholders, signs and symbols, decimal commas, separators, percentages. Mark anything unrecognised instead of turning it into ",[13,1999,27],{},", and fix the source so the problem does not return.",[40,2002,2004],{"id":2003},"frequently-asked-questions","Frequently asked questions",[10,2006,2007,2010],{},[1947,2008,2009],{},"How do I fix \"could not convert string to float\" in pandas?","\nFind the failing values with pd.to_numeric(column, errors=\"coerce\") compared with the original, see why they fail, and clean them with explicit rules before converting.",[10,2012,2013,2016],{},[1947,2014,2015],{},"How do I find which values cannot be converted to numbers?","\nSelect rows where pd.to_numeric(column, errors=\"coerce\") is NaN but the original value is not empty, and print the repr of each value.",[10,2018,2019,2022],{},[1947,2020,2021],{},"Why does a number that looks fine fail to convert?","\nIt probably contains an invisible character such as a non-breaking space or a Unicode minus sign; repr() shows them.",[10,2024,2025,2028],{},[1947,2026,2027],{},"How do I convert numbers with a decimal comma like 1.234,56?","\nRemove the dots used as thousands separators and replace the comma with a dot before converting, or read CSV files with thousands=\".\" and decimal=\",\".",[40,2030,2032],{"id":2031},"related","Related",[1941,2034,2035,2041,2048,2055],{},[1944,2036,2037,2038,2040],{},"Up one level: ",[34,2039,37],{"href":36}," — fixes for common errors.",[1944,2042,2043,2047],{},[34,2044,2046],{"href":2045},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-number-stored-as-text-warnings-in-excel-output\u002F","Fix Number Stored as Text Warnings in Excel Output"," — the same problem on the writing side.",[1944,2049,2050,2054],{},[34,2051,2053],{"href":2052},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets\u002Fparse-numbers-with-units-in-excel-cells\u002F","Parse Numbers with Units in Excel Cells"," — values like \"12 kg\".",[1944,2056,2057,2061],{},[34,2058,2060],{"href":2059},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fremove-accents-and-normalise-unicode-in-excel-text\u002F","Remove Accents and Normalise Unicode in Excel Text"," — more on invisible characters.",[2063,2064,2065],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .s_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":50,"searchDepth":109,"depth":109,"links":2067},[2068,2069,2070,2071,2072,2073,2074,2075,2076,2077,2078],{"id":42,"depth":109,"text":43},{"id":82,"depth":109,"text":83},{"id":391,"depth":109,"text":392},{"id":948,"depth":109,"text":949},{"id":1896,"depth":109,"text":1897},{"id":1907,"depth":109,"text":1908},{"id":1914,"depth":109,"text":1915},{"id":1938,"depth":109,"text":1939},{"id":1987,"depth":109,"text":1988},{"id":2003,"depth":109,"text":2004},{"id":2031,"depth":109,"text":2032},"2026-10-02","Fix ValueError: could not convert string to float when converting an Excel column with pandas: find exactly which cells fail and why, then clean thousands separators, currency symbols, percentages, accounting negatives in parentheses, non-breaking spaces, Unicode minus signs, European decimal commas and placeholder text — and report what could not be converted instead of hiding it.","md",[2083,2085,2087,2089],{"q":2009,"a":2084},"Find the failing values with pd.to_numeric(column, errors=\"coerce\") compared with the original, see why they fail, and clean them with explicit rules before converting.",{"q":2015,"a":2086},"Select rows where pd.to_numeric(column, errors=\"coerce\") is NaN but the original value is not empty, and print the repr of each value.",{"q":2021,"a":2088},"It probably contains an invisible character such as a non-breaking space or a Unicode minus sign; repr() shows them.",{"q":2027,"a":2090},"Remove the dots used as thousands separators and replace the comma with a dot before converting, or read CSV files with thousands=\".\" and decimal=\",\".","could not convert string to float excel pandas",null,{"breadcrumb":2094},[2095,2097,2100],{"name":2096,"item":1334},"Home",{"name":2098,"item":2099},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":37,"item":36},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-could-not-convert-string-to-float-in-excel-data",{"title":5,"description":2103},"Solve pandas ValueError could not convert string to float on Excel columns: locate failing cells with to_numeric, handle commas, currency, %, (negatives), NBSP, Unicode minus, decimal commas and N\u002FA, and report leftovers.","fix-could-not-convert-string-to-float-in-excel-data","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-could-not-convert-string-to-float-in-excel-data\u002Findex",[2107,2108],"troubleshooting","data-cleaning","how-to","C3jk51JZgKZiC52wBhxR9QNJoG0Tt2w-JeYmczRlh7E",[2112,2116],{"title":2113,"path":2114,"stem":2115,"children":-1},"Fix \"ValueError: Cannot convert to Excel\" in openpyxl","\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-cannot-convert-to-excel-valueerror","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-cannot-convert-to-excel-valueerror\u002Findex",{"title":2117,"path":2118,"stem":2119,"children":-1},"Fix the \"Data Validation extension is not supported\" Warning in openpyxl","\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-data-validation-extension-is-not-supported-warning","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-data-validation-extension-is-not-supported-warning\u002Findex",[2121,2123],{"path":2122,"title":2098},"\u002Fgetting-started-with-python-excel-automation",{"path":2124,"title":37},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors",[],[2127,2130,2133,2136,2139,2142],{"path":2128,"title":2129,"kind":815},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation\u002Fhandle-permission-denied-when-writing-excel-in-python","Handle Permission Denied When Writing Excel in Python",{"path":2131,"title":2132,"kind":2109},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fwhat-openpyxl-loses-when-saving-an-existing-workbook","What openpyxl Loses When You Save an Existing Workbook",{"path":2134,"title":2135,"kind":815},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-dates-and-times-in-excel-data\u002Ffix-excel-serial-numbers-showing-instead-of-dates","Fix Excel Serial Numbers Showing Instead of Dates",{"path":2137,"title":2138,"kind":2109},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-dates-and-times-in-excel-data\u002Fhandle-daylight-saving-time-in-excel-timestamps","Handle Daylight Saving Time in Excel Timestamps",{"path":2140,"title":2141,"kind":2109},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fhandle-microsoft-graph-throttling-for-excel","Handle Microsoft Graph Throttling in Excel Automation",{"path":2143,"title":2144,"kind":2145},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation","Error Handling and Logging in Excel Automation","guide",1790972065495]