【问题标题】:Can't find correct codec for reading csv找不到用于读取 csv 的正确编解码器
【发布时间】:2019-07-04 11:26:12
【问题描述】:

我正在读取一个 csv 文件,这是来自网络协议、十六进制字符和普通混合的一些痕迹。 我正在尝试读取 .csv,并且尝试了几种编码:utf-8、cp1252、latin1...

对于latin1

UnicodeEncodeError: 'ascii' codec can't encode character u'\xb0' in position 51: ordinal not in range(128)

对于 utf-8

UnicodeDecodeError: 'utf8' codec can't decode byte 0xb0 in position 51: invalid start byte

对于cp1252

UnicodeEncodeError: 'ascii' codec can't encode character u'\xb0' in position 51: ordinal not in range(128)

使用的代码是:

df=pd.read_csv(file,sep='`',error_bad_lines=False,encoding='cp1252',names=colnames,quotechar='"')

我不是编码方面的专家,但我想知道如何解决它。

找出我正在阅读的 csv 文件的当前编码?

是否有一个非常宽松的编解码器可以处理几乎所有内容?

谢谢。

【问题讨论】:

  • 你的 csv 里面有什么?
  • 对于 utf-8,您会在 read_csv 中得到预期的 UnicodeDecodeError,因为它包含非 utf-8 字符。对于 Latin1 和 cp1252,您可能会在不同的指令中获得 UnicodeEncodeError(注意 Encode 而不是 Decode)。我需要完整的堆栈跟踪和相关代码才能为您提供帮助。
  • 只有作者知道字符编码。询问、阅读文档、适用标准或观察其通信方式(例如,HTTP 响应标头 Content-Type。)或者 - 如果源支持它 - 使用不受此问题影响的格式,例如 . ods 或 .xlsx。
  • 使用cp1252 你不应该得到错误'ascii' codec can't encode character u'\xb0'。您只能通过ascii 获得它。使用b'\xb0'.decode('cp1252') 我看到它可以是°(度数符号)
  • @furas 所说的关于 latin1 和 cp1252 的说法都是正确的。 Latin1 是您的答案(在以任何顺序使用所有 256 字节值的数十种字符编码中)。似乎是一个糟糕的测试导致了这个问题。

标签: python pandas utf-8 ascii codec


【解决方案1】:

CSV 是一种文本格式;它并不适合存储任意二进制数据。

要解决您当前的问题,您可以指定´latin-1' 作为编码。该编解码器的独特之处在于每个单字节字符对应完全相同的 Unicode 码位。

但请注意,如果您不小心,这可能会产生各种mojibake。您可能应该提取任何二进制数据,然后尽快将剩余字段解码为正确的 Unicode。这是一个用于 UTF-8 的简单纯 Python sn-p,其中一个字段包含二进制。

with open(filename, encoding='latin-1') as input:
    reader = csv.reader(input)
    for row in reader:
        binary = row[42].encode('latin-1')
        newrow = []
        for field in row:
            newrow.append(field.encode('latin-1').decode('utf-8'))
        newrow[42] = binary
        # newrow is now decoded UTF-8 except field 42 which is a bytes object

【讨论】:

  • 我对 Pandas 不够熟悉,无法提供pd 解决方案,但我希望从中推导出一个解决方案并不难。
【解决方案2】:

先找出编码类型,然后用它来读取

查找编码类型:

方法:1 您可以使用记事本打开文件,然后转到文件 -> 另存为。保存按钮旁边会有一个编码下拉菜单,文件的当前编码将在此处选择。 方法:2 在Linux系统中,可以使用file命令。它会给出正确的编码

    > file sub01.csv

sub01.csv:ASCII 文本

【讨论】:

  • 请删除那个非回答。最多只能是评论(我知道您目前没有足够的代表。)。无论如何这是错误的,因为Latin1 只是iso-8859-1 的别名。
  • file 没有给出“正确”的编码。它根据样本给出了许多可能的编码之一。也就是说,它接近于所要求的:“允许的”编码。对于该样本,file 的答案将是“允许的”。
【解决方案3】:

用于读取 csv 文件

import csv
def unicode_csv_reader(utf8_data, dialect=csv.excel, **kwargs):
   csv_reader = csv.reader(utf8_data, dialect=dialect, **kwargs)
   for row in csv_reader:
      yield [unicode(cell, 'utf-8') for cell in row]
   filename = 'da.csv'
   reader = unicode_csv_reader(open(filename))
   for field1, field2, field3 in reader:
       print field1, field2, field3 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    • 2013-09-21
    • 1970-01-01
    • 2015-08-28
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    相关资源
    最近更新 更多