在 pandas 中加载带有二进制数据的 CSV 文件

Qua*_*um7 2 python csv pandas python-unicode

我正在尝试解析 CSV 文件(来自外部数据源),其中其中一列使用不一致的字符编码。我不想尝试让数据提供者使用一致的编码,而是只想将该列读取为二进制数据。然而,pandas.read_csv似乎在解析之前将整个文件解码为字符串,因此这给了我错误(UnicodeDecodeError)。这是一个玩具示例(python 3):

\n\n
>>> 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\n
Run 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\'\n
Run 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\n
Run Code Online (Sandbox Code Playgroud)\n\n

我更喜欢仅使用 pandas 的解决方案,但如果绝对必要,我愿意查看其他解析库。

\n

Vee*_*Vee 8

根据Serge Ballesta回答这篇文章的说法

\n\n

“Pandas 允许指定编码,但不允许忽略错误而不自动替换有问题的字节。因此,没有一种适合所有方法,而是根据实际用例采用不同的方法。”

\n\n
    \n
  1. 因此,首先,尝试使用Latin1编码,因为它接受任何可能的字节作为输入,并且根据您的用例可能就足够了(我可以使用这个来运行您的玩具示例):

    \n\n
    data_frame = pd.read_csv(BytesIO(csv), encoding="latin1"))\n
    Run Code Online (Sandbox Code Playgroud)
  2. \n
  3. 正如 Serge 的回答中所指出的:“Pandas 没有提供特殊的错误处理,但 Pythonopen函数有(假设 Python3),并且read_csv接受类似文件的对象。” 对于您的情况,您可以考虑使用\'backslashreplace\'它用 Python\xe2\x80\x99s 反斜杠转义序列替换有问题的字节:

    \n\n
    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)\n
    Run Code Online (Sandbox Code Playgroud)
  4. \n
\n