Записать байты из savReader с помощью csv.writer без даты конвертации - PullRequest
0 голосов
/ 16 мая 2018

Я хочу прочитать данные из файла .sav (SPSS) и переписать их в .csv для дальнейшего использования.Для чтения я использую savReaderWriter.SavReader, и он возвращает все строки в байтовой записи: b'string' вместо 'string'.

Ниже приведен мой код в Python 3.6:

import savReaderWriter
import csv

with savReaderWriter.SavReader('input_filename.sav') as reader:
    header = reader.header
    with open('output_filename.csv','w',newline='') as output:
        w = csv.writer(output,delimiter=',')
        w.writerow(header)
        for line in reader:
            w.writerow(line)

OneРешение, которое я нашел, состоит в том, чтобы указать ioUtf8=True в SavReader, но затем все переменные даты преобразуются в число с плавающей точкой: b'2017-09-02' становится 13723689600.0, который затем читается datetime.fromtimestamp как год 2404.

Еще одна вещь, которая работает, это

w.writerow([h.decode('utf-8') for h in header])

, но только для заголовка, так как другие строки содержат числа с плавающей запятой и нани и, следовательно, вызывают ошибки.

Указание 'wb' вместо 'w' in open также возвращает ошибку:

TypeError: a bytes-like object is required, not 'str'

Есть идеи, как правильно читать и записывать данные такого типа?

1 Ответ

0 голосов
/ 19 мая 2018

Я нашел временное решение, хотя я не горжусь этим.Может быть, кто-то еще может улучшить его.

import savReaderWriter
import csv

utf_errors = 0
with savReaderWriter.SavReader('input_filename.sav') as reader:
    header = reader.header
    header = [h.decode('utf-8') for h in header]
    with open('output_filename.csv','w',newline='') as output:
        w = csv.writer(output,delimiter=',')
        w.writerow(header)
        for line in reader:
            newline = []
            for l in line:
                try:
                    newline += [l.decode('utf-8')]
                except AttributeError:
                    # for non-string (floats and nan-s)
                    newline += [l]
            try:        
                w.writerow(newline)
            except UnicodeEncodeError:
                    # omit row when an unknown character is found
                    utf_errors += 1
                    pass

read_output = pd.read_csv(path+'output_filename.csv', encoding='latin1') 

Странная вещь в данных состоит в том, что, как бы я ни декодировал их, всегда есть символы, которые невозможно прочитать.Я нашел его наиболее эффективным с .decode('utf-8') (пропускает 4 строки) по сравнению с .decode('latin1') (пропускает 29 строк), но затем мне нужно прочитать его с encoding='latin1', в противном случае я получаю эту ошибку:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 9: invalid continuation byte
...