2016-05-16 44 views
1

我有一个相当大的数据库(10,000多条记录,每个记录大约有120个变量)。问题是,大约一半的原始.csv文件中的变量被正确编码为UTF-8而其余的则以ANSI(Windows-1252)编码,但被解码为UTF-8,导致非ASCII字符(主要是拉丁字符)的奇怪字符,如éócsv文件中的混合编码

我不能简单地改变文件编码,因为它的一半将被解码为错误的类型。此外,我无法知道哪些列编码正确,哪些没有正确编码,而我所拥有的就是我试图修复的原始.csv文件。

到目前为止,我发现纯文本文件可以使用UTF-8编码,并且可以推断出错误解释的字符(错误的Unicode)。一个提供这种功能的库是Python的ftfy。但是,我使用下面的代码,到目前为止,还没有成功:

import ftfy 

file = open("file.csv", "r", encoding = "UTF8") 
content = file.read() 

content = ftfy.fix_text(content) 

然而,content将准确显示比以前相同的文本。我相信这与ftfy推断内容编码的方式有关。

不过,如果我跑ftfy.fix_text("Pública que cotiza en México")它会显示正确的反应:

>> 'Pública que cotiza en México' 

我在想,也许解决问题的方法是通过在每一个的值(细胞)进行迭代。 csv文件,并尝试修复如果与ftfy,并将文件导回到R,但它似乎有点复杂

有什么建议吗?

+1

如果该文件是混合编码,并且您使用的是UTF-8,那么您会在所有位置都收到UnicodeDecode错误。这听起来更像是字符被错误地存储在数据库中。按照建议使用ftfy。也许在返回结果 –

回答

2

实际上,有几种随机单元的混合编码地方。从其原始源导出数据时可能存在问题。

ftfy的问题在于它一行一行地处理文件,并且如果遇到格式化的字符,它会假设整行以相同的方式编码,并且意图使用奇怪的字符。

由于这些错误是通过所有文件随机出现的,因此我无法转置整个表并处理每一行(列),所以答案是逐个处理。幸运的是,Python有一个标准库,它提供了使用csv轻松工作的功能(特别是因为它正确地转义了单元格)。

这是我用来处理文件的代码:

import csv 
import ftfy 
import sys 

def main(argv): 
    # input file 
    csvfile = open(argv[1], "r", encoding = "UTF8") 
    reader = csv.DictReader(csvfile) 

    # output stream 
    outfile = open(argv[2], "w", encoding = "Windows-1252") # Windows doesn't like utf8 
    writer = csv.DictWriter(outfile, fieldnames = reader.fieldnames, lineterminator = "\n") 

    # clean values 
    writer.writeheader() 
    for row in reader: 
     for col in row: 
      row[col] = ftfy.fix_text(row[col]) 
     writer.writerow(row) 

    # close files 
    csvfile.close() 
    outfile.close() 

if __name__ == "__main__": 
    main(sys.argv) 

,然后美其名曰:

$ python fix_encoding.py data.csv out.csv 

将输出与正确的编码csv文件。

+0

好的解决方案前写一个围绕CSV模块的包装来解析通过ftfy。尽管我发现使用csv.reader和csv.writer更简单,因为您不必处理标题,字典等。 – AlexanderMP

1

一个小建议:分而治之。 尝试使用一个工具(ftfy?)将所有文件对齐到相同的编码(并保存为纯文本文件),然后尝试解析为csv