Qua*_*um7 2 python csv pandas python-unicode
我正在尝试解析 CSV 文件(来自外部数据源),其中其中一列使用不一致的字符编码。我不想尝试让数据提供者使用一致的编码,而是只想将该列读取为二进制数据。然而,pandas.read_csv似乎在解析之前将整个文件解码为字符串,因此这给了我错误(UnicodeDecodeError)。这是一个玩具示例(python 3):
>>> from io import BytesIO\n>>> import pandas as pd\n>>> csv = b\'Encoding,Data\\nascii,abc\\nwindows-1252,\\xae\\nutf-8,\\xe2\\x80\\x9c1\\xe2\\x80\\x9d\\n\'\n>>> pd.read_csv(BytesIO(csv))\nTraceback (most recent call last):\n File "pandas/_libs/parsers.pyx", line 1130, in pandas._libs.parsers.TextReader._convert_tokens\n File "pandas/_libs/parsers.pyx", line 1254, in pandas._libs.parsers.TextReader._convert_with_dtype\n File "pandas/_libs/parsers.pyx", line 1269, in pandas._libs.parsers.TextReader._string_convert\n File "pandas/_libs/parsers.pyx", line 1459, in pandas._libs.parsers._string_box_utf8\nUnicodeDecodeError: \'utf-8\' codec can\'t decode byte 0xae in position 0: invalid start byte\nRun Code Online (Sandbox Code Playgroud)\n\n我想要一个与此等效的结果:
\n\n>>> df = pd.DataFrame({\'Encoding\': [\'ascii\',\'windows-1252\',\'utf-8\'],\n... \'Data\': [b\'abc\',b\'\\xae\',b\'\\xe2\\x80\\x9c1\\xe2\\x80\\x9d\']})\n>>> df\n Encoding Data\n0 ascii b\'abc\'\n1 windows-1252 b\'\\xae\'\n2 utf-8 b\'\\xe2\\x80\\x9c1\\xe2\\x80\\x9d\'\nRun Code Online (Sandbox Code Playgroud)\n\n可以(在这个玩具示例中)进一步处理如下:
\n\n>>> df.apply(lambda row: str(row.Data,row.Encoding), axis=1)\n0 abc\n1 \xc2\xae\n2 \xe2\x80\x9c1\xe2\x80\x9d\ndtype: object\nRun Code Online (Sandbox Code Playgroud)\n\n我更喜欢仅使用 pandas 的解决方案,但如果绝对必要,我愿意查看其他解析库。
\n“Pandas 允许指定编码,但不允许忽略错误而不自动替换有问题的字节。因此,没有一种适合所有方法,而是根据实际用例采用不同的方法。”
\n\n因此,首先,尝试使用Latin1编码,因为它接受任何可能的字节作为输入,并且根据您的用例可能就足够了(我可以使用这个来运行您的玩具示例):
data_frame = pd.read_csv(BytesIO(csv), encoding="latin1"))\nRun Code Online (Sandbox Code Playgroud)正如 Serge 的回答中所指出的:“Pandas 没有提供特殊的错误处理,但 Pythonopen函数有(假设 Python3),并且read_csv接受类似文件的对象。” 对于您的情况,您可以考虑使用\'backslashreplace\'它用 Python\xe2\x80\x99s 反斜杠转义序列替换有问题的字节:
file_encoding = \'utf8\' # set file_encoding to the file encoding (utf8, latin1, etc.)\nwith open(path_to_csv, encoding=file_encoding, errors = \'backslashreplace\') as my_csv:\n dataframe = pd.read_csv(my_csv)\nRun Code Online (Sandbox Code Playgroud)