Skip to content
Start free

How do I read a file from another country correctly in pandas?

Read the Valencia price list step by step with the separator, decimals, thousands and encoding spelled out, and compute the inventory's value.

Free course. Your Maestro, an AI, .

You have the pieces: the separator, the decimal mark, thousands and the BOM. Now put them all together in a single read. The full version of the Valencia price list has five products, and one costs more than a thousand:

datos/lista_precios.csv
sku;descripcion;precio;existencias
00731;Cuaderno profesional;23,50;380
01204;Plumas azules (caja);118,00;64
00090;Goma blanca;9,90;1200
09810;Mochila escolar;1.180,00;15
00412;Lápiz adhesivo;14,75;540
Synthetic data, CC0. The file, seen as text.

And it starts with a BOM, which you can't see here but is in the first three bytes. Your boss wants to know what the supplier's inventory is worth: price times stock, summed. Before writing code, this is how someone with experience would solve it. Try each step before you open it.

Reading the Valencia price list

Worked example · 5 steps

The file datos/lista_precios.csv uses semicolons, a decimal comma, a period for thousands and a BOM. It has to be read in pandas so that precio and existencias are numbers and can be multiplied.

Work out the next step yourself, then open it to compare.

Try it

The inventario.py script reads the list without any option and fails. Add to pd.read_csv what it needs and run it with uv run inventario.py. Do it one option at a time and run again each time: watching how the error changes teaches too. If the error changes and you don't know what it's telling you, paste it to your Maestro.

Your turn

Run uv run inventario.py and read the error. Add to pd.read_csv the separator, the decimal mark, the thousands separator and the encoding that datos/lista_precios.csv uses. You're done when it prints the four columns and Inventory value: $54,027.00.

    Python 3.12· runs with your account

    What happens halfway

    If you added sep=";" and decimal="," but not yet thousands=".", the error you saw doesn't mention commas or thousands. It says something like ValueError: Unknown format code 'f' for object of type 'str', on the last line. It's worth understanding why, because it's a trap that shows up a lot.

    Since 1.180,00 isn't a valid number for pandas without thousands, the whole precio column stays as text. And in Python, text times a number isn't an error: it repeats the text. "1.180,00" * 15 gives 1.180,001.180,00... fifteen times in a row. We ran it in the sandbox: the backpack's valor ends up as a 120-character text. The multiplication "worked", the sum glued all those texts into one, and the program only complained at the end, when you asked it to format a text as money.

    The lesson isn't to memorize that message. It's this: an error at the end of the script can come from a bad read at the beginning. That's why the last step of the worked example was checking dtypes before calculating. If precio says str, don't go on: go back to read_csv.

    A single cell is enough for this to happen. The other four rows of the list would read fine with decimal=","; it's the backpack, the only one over a thousand, that leaves the whole column as text. In your work files it's usually the same: the problem is in the row you didn't check.

    Ask your Maestro to help you find which row leaves a column as text.

    Notice what you did not do: you didn't open the file to replace commas with periods, or ask the supplier to send it differently. The file is fine; you told pandas how to read it. If October's list arrives tomorrow, the same script reads it the same way.

    A pd.read_csv line with its options in plain view is documentation too: whoever reads your script later knows, without opening the file, that it comes with semicolons, decimal commas and a BOM. Ask your Maestro what other read_csv options could be useful with your files.

    Check yourself: You read a file with sep=';' and decimal=',', and the precio column still comes out as text (str). The other columns look fine. What's most likely?