How to create a CSV file via Python by keeping the decimal separator in the same place?

Asked

Viewed 1,245 times

0

I have a Python script that makes a request via API and saves the data in a CSV file. The data is stored in different lists in Python and should be saved in different columns in the CSV file. The dates of the lists are originally in Unicode (I tried, too, to transform to float and str before converting to CSV, but unsuccessfully). If I open the generated CSV file in Notepad++ (eg) the data appears exactly as I want it to:

01/02/2019 01:00:00;568.5200;608.7472;654.1030
01/02/2019 02:00:00;577.7830;608.2220;653.7230

However, if I open with Excel, the data appears like this (in separate columns):

01/02/2019 01:00:00 5.685.200   6.087.472   6.541.030
01/02/2019 02:00:00 5.777.830   6.082.220   6.537.230

Notice how the decimal separator was placed in the wrong place (if I click on the cell, the entered value is taken as integer, or 5685200, for example).

The funny thing is, if I open the csv file with Google Sheets, it doesn’t do any sorting by the delimiter (';') and writes all the data in one line.

I’m using izip and writer.writerows to convert the lists into columns in a CSV file.

import csv
from itertools import izip

#Um monte de código

with open('Latencia.csv', 'wb') as csvfile:
    writer = csv.writer(csvfile, delimiter = ';')
    writer.writerows(izip(dates, values_min, values_avg, values_max))

I need to change my data formatting for Excel or Google Sheets to open the CSV file the way I want it to?

  • 1

    See if this answer help you, because Excel in Portuguese uses the delimiter ;, already the Notepad++ ,. Excel in Portuguese uses the , as decimal separator... You can open the csv file manually by Excel and choose settings, delimiters, etc.

1 answer

1


Your biggest problem in the case is Excel and has nothing to do with Python - he is assuming that the "locality" (localization) of his CSV is in "Brazilian Portuguese", and, in that locality, the "." is the separator of thousands - the "," is what would be the serparador of decimal places.

If in the Excel import you have to make explicit that the file is using the "locality" "EN-US", your problem goes away.

If you prefer not to touch Excel at the time of import, and keeping in mind that your file will only work for Excel in Brazil, and will have to be manually configured both for import into other software, how much to import into Excel itself on a machine where the default language and location is not Portuguese of Brazil you can choose to write the numbers with "," instead of "." , making the conversion from Python.

To do this, simply pass your sequence of numbers through a simple generator that does the conversion. The conversion could simply be: ensure that the number is a string, and replace "," by "." - but this is not very elegant - the ideal would be to use location formatting - especially if your script is part of a large system (which can be used by sectors of your company abroad, or which will be published as open source, for example).

The logic of the generator itself is quite simple - a function that takes the sequence of numbers, and for each number does the yield in the transformed form

import csv
import locale
from itertools import izip


#Um monte de código


locale.setlocale(locale.LC_ALL, "pt_BR.utf-8")

def format(numbers):
    for number in numbers:
        yield locale.format_string("%f", float(number))

with open('Latencia.csv', 'wb') as csvfile:
    writer = csv.writer(csvfile, delimiter = ';')
    writer.writerows(izip(dates, format(values_min), format(values_avg), format(values_max)))


# Sem se preocupar com a fazer "certo" a parte de localização, a função poderia ser:

def format(numbers):
    for number in numbers:
        yield str(number).replace(".", ",")

-It would be possible to use a Generator, make a simple function, to convert a single number, and use the function map - but that would involve writing three times on the call to write something like map(format, values_min) instead of format(values_min) - gets more verbose.

(if you are going to use Python 3 - (please do this), take out the "b" in the file opening mode, the "i" of the "izip"). By coincidence, the use of locale format_string is the same in the above code.)

Finally

You may notice that maybe CSV is not the best way to transpose your data from one side to the other - a more deterministic format, which does not depend on the individual settings of the software that will read the data may be more appropriate. Python allows you to create files .xlsx directly in almost as simple a way as creating a .csv, simply importing the correct library. For example, here I installed the module with pip install openpyxl - takes less than 15 seconds - and then I typed this sequence into the interactive terminal:

import openpyxl
import datetime
wb = openpyxl.Workbook()
sheet = wb.active
row1 = ["nome1", datetime.date.today(), 1232434.12345, 1234567.8901, 123456.98765]
for i in range(5): sheet.append(row1)
wb.save("teste.xlsx") 

Done - no conversion needed - the data appeared as it should in the spreadsheet program (in this case, Libreoffice): numbers being numbers, dates being dates, text being text! And it would be easy to create other pages (Sheets) in the spreadsheet, plus other controls.

Of course, to have functional versions of such libraries, I repeat, it is important that you be in an updated version of Python. 2.7 is an old version of the language, which was released 10 years ago and is at the end of its useful life.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.