使用csv.writer从savReader写入没有日期的字节到浮点转换

时间:2018-05-16 15:42:16

标签: python csv utf-8 spss

我想从.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)

我找到的一个解决方案是在ioUtf8=True中指定SavReader但是所有日期变量都转换为浮点数:b'2017-09-02'变为13723689600.0然后读取由datetime.fromtimestamp作为2404年。

另一件有效的事情是

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

但仅限于标题,因为其他行包含浮点数和nan-s,因此会产生错误。

'wb'中指定'w'而不是open也会返回错误:

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

有关如何正确读取和写入此类数据的任何想法吗?

1 个答案:

答案 0 :(得分:0)

我找到了一个临时解决方案,虽然我并不为此感到骄傲。也许其他人可以改进它。

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'读取它,否则我会收到此错误:< / p>

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