Pandas to_csv: ASCII无法编码字符。

23

我正在尝试将一个数据框读写到一个以管道分隔的文件中。其中有些字符是非罗马字母(`, ç, ñ等)。但当我尝试将重音符号写成ASCII时,它会出错。

df = pd.read_csv('filename.txt',sep='|', encoding='utf-8')
<do stuff>
newdf.to_csv('output.txt', sep='|', index=False, encoding='ascii')

-------

  File "<ipython-input-63-ae528ab37b8f>", line 21, in <module>
    newdf.to_csv(filename,sep='|',index=False, encoding='ascii')

  File "C:\Users\aliceell\AppData\Local\Continuum\Anaconda3\lib\site-packages\pandas\core\frame.py", line 1344, in to_csv
    formatter.save()

  File "C:\Users\aliceell\AppData\Local\Continuum\Anaconda3\lib\site-packages\pandas\formats\format.py", line 1551, in save
    self._save()

  File "C:\Users\aliceell\AppData\Local\Continuum\Anaconda3\lib\site-packages\pandas\formats\format.py", line 1652, in _save
    self._save_chunk(start_i, end_i)

  File "C:\Users\aliceell\AppData\Local\Continuum\Anaconda3\lib\site-packages\pandas\formats\format.py", line 1678, in _save_chunk
    lib.write_csv_rows(self.data, ix, self.nlevels, self.cols, self.writer)

  File "pandas\lib.pyx", line 1075, in pandas.lib.write_csv_rows (pandas\lib.c:19767)

UnicodeEncodeError: 'ascii' codec can't encode character '\xb4' in position 7: ordinal not in range(128)

如果我将 to_csv 更改为 utf-8 编码,那么我就不能正确地读取文件:
newdf.to_csv('output.txt',sep='|',index=False,encoding='utf-8')
pd.read_csv('output.txt', sep='|')

> UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb4 in position 2: invalid start byte

我的目标是拥有一个保留重音符号和特殊字符的管道分隔文件。

另外,有没有一种简单的方法可以找出read_csv在哪一行出错?目前我不知道如何让它显示错误字符。


1
可能是Pandas将数据帧写入CSV文件的重复问题。 - mbecker
你是否对Unicode字符串进行了规范化以去除重音符号?我认为ASCII无法处理那些字母... - juanpa.arrivillaga
@juanpa.arrivillaga:我编辑了我的帖子,以澄清我对输出的要求。 - ale19
@ale19 你不能在ASCII中编码重音和特殊字符。这是一种基本的表示形式。这就是为什么像UTF-8这样的编码存在的原因。只需用UTF-8写出即可。 - juanpa.arrivillaga
5个回答

73

检查答案在这里

这是一个简单得多的解决方案:

newdf.to_csv('filename.csv', encoding='utf-8')

10

您有一些非ASCII字符,因此无法像您尝试的那样进行编码。我建议只使用评论中提到的utf-8

要检查导致问题的哪些行,您可以尝试类似以下内容的操作:

def is_not_ascii(string):
    return string is not None and any([ord(s) >= 128 for s in string])

df[df[col].apply(is_not_ascii)]

您需要指定要测试的列 col


谢谢。当我尝试使用您的函数(指定列)时,出现TypeError:ord()期望一个字符,但找到长度为17的字符串。我猜这是因为ord()检查单个字符,但所涉及的列包含字符串。 - ale19
如果您执行 df[df[col].apply(is_ascii) ==False],则只会获取包含错误的行/索引。 - dreab

1
另一种解决方案是使用字符串函数编码/解码,并选择使用“ignore”选项,但这将删除非ASCII字符:
df ['text'] = df ['text'] .apply(lambda x:x.encode('ascii','ignore').decode('ascii'))

1

尝试这个,它有效

newdf.to_csv('文件名.csv', encoding='utf-8')


0

当我读取包含拉丁字符的csv文件时,例如:á,é,í,ó,ú,ñ等,我的解决方案是使用:encoding='latin_1'

df = pd.read_csv('filename.txt',sep='|', encoding='latin_1')
<do stuff>
newdf.to_csv('output.txt', sep='|', index=False, encoding='latin_1')

您可以在此文档中阅读完整的编码列表: [Python标准编码列表][1]。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接