使用以下代码:
import pandas as pd
filename = r"/path/to/my/file.csv"
with open(filename) as f:
data_frame = pd.read_csv(f,
usecols=['col1', 'col2'],
parse_dates=['DateProd', 'DateStart', 'DateEnd'],
header=0,
delimiter=';',
encoding='latin-1')
print(data_frame)
当在本地执行时,它会以适当的强调打印预期的数据帧。当在远程工作人员上的 Airflow 任务中执行时,它会失败并出现以下错误:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 2581: invalid continuation byte
当查看完整的调试跟踪跟踪(抱歉,敏感信息,无法完全提供)时,我在堆栈跟踪中看到明确指定了encoding='latin-1',但它仍然失败并出现 UnicodeDecodeError 错误。有人注意到类似的问题吗?我一直在兜圈子,尝试尽可能多的编码,但似乎没有任何效果。
我忘了提及该文件是 samba 共享上的远程文件。无论我尝试使用 smbclient.open() 直接读取它还是将其复制到本地然后打开它,我都会得到相同的结果:UnicodeDecodeError。当我在本地尝试同样的事情时(直接从 samba 共享读取,或复制它),一切看起来都很好,而且我注意到我什至不需要指定编码,它会自动找到它,并且重音将是正确显示。
另一个更新:似乎文件是否从 samba 共享读取并没有什么区别。我设法运行在远程工作人员上使用的 docker 镜像,并且我可以使用本地托管的所有内容重现此问题,无论我之前打开该文件,还是在将其提供给 pandas 之前完全阅读它,或者我是否只是提供文件名改为 read_csv。
引擎似乎也没有什么区别:指定engine='python' 或engine='c' 会产生相同的结果。
另一个更新:看来新的 ubuntu docker 镜像也发生了同样的问题。我猜测需要安装一些语言环境才能解析它们。
最佳答案
我已经弄清楚了。
在 Windows 计算机上,默认编码似乎有所不同。我什至不必指定它的编码即可工作。不在容器内。因此,我需要在打开容器中的文件时指定编码。以下内容应该有效:
import pandas as pd
filename = r"/path/to/my/file.csv"
with open(filename, encoding='latin-1') as f:
data_frame = pd.read_csv(f,
usecols=['col1', 'col2'],
parse_dates=['DateProd', 'DateStart', 'DateEnd'],
header=0,
delimiter=';',)
# Notice the lack of encoding='latin-1' here.
print(data_frame)
但是! SambaHook 本质上返回 pysmbclient 的 SambaClient。当您尝试使用此 Samba 客户端打开文件时,无法指定文件的编码。因此,在本地 Windows 机器上,一切似乎都工作正常。在 Linux 容器中,它会失败并出现 UnicodeDecodeError。仔细观察,我发现它本质上是在对文件调用 open() 之前复制文件。
目前,这是我的解决方案:将文件与 SambaHook 返回的 SambaClient 一起复制到临时文件中,使用正确的编码打开它,让 panda 解析它。我将了解如何改进 SambaHook 和 pysmbclient,以便其他人可以在打开文件时指定编码。
关于python - 使用 pandas 解析文件时 Airflow Worker 不理解文件编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52506112/