python - 将 Pandas DataFrame 作为 Pickle 写入 S3
问题描述
这是我的要求。
- 将 pandas 数据帧作为 pickle 文件上传到 AWS S3
- 由于环境原因,必须使用 boto3 并且不能选择 s3fs 等替代方案
- 数据必须存在于内存中,不能写入临时文件
我创建了以下简单的函数,将 Pandas 数据帧作为 csv 上传到 s3:
def df_to_s3_csv(df, filename, sep=','):
s3 = boto3.resource('s3')
buffer = io.StringIO()
df.to_csv(buffer, sep=sep, index=False)
s3.Object(s3bucket, f'{s3_upload_path}/{filename}').put(Body=buffer.getvalue())
此功能工作正常,并完成了它应该做的事情。对于泡菜文件,我以类似的方式创建了以下函数:
def df_to_s3_pckl(df, filename):
s3 = boto3.resource('s3')
buffer = io.BytesIO()
df.to_pickle(buffer)
buffer.seek(0)
obj = s3.Object(s3bucket, f'{s3_upload_path}/{filename}')
obj.put(Body=buffer.getvalue())
我在有和没有部分的情况下尝试了这个函数,seek
无论哪种方式它都会引发以下错误:ValueError: I/O operation on closed file.
进一步研究这个问题,我发现一旦被调用就buffer
被认为是。这可以通过发出以下命令来重现:closed
df.to_pickle
buffer = io.BytesIO()
df.to_pickle(buffer)
print(buffer.closed)
以上打印True
。似乎BytesIO
缓冲区已关闭to_pickle
,因此无法引用其数据。如何解决此问题,或者是否有满足我要求的替代方案?我在 SO 上发现了几个关于如何使用 boto3 上传到 S3 的问题,但没有关于如何使用 BytesIO 缓冲区上传 Pandas 创建的泡菜文件。
这是潜在问题的最小可重现示例:
import pandas as pd
import numpy as np
import io
df = pd.DataFrame(np.random.randint(0,100,size=(4,4)))
buffer = io.BytesIO()
df.to_pickle(buffer)
print(buffer.closed)
解决方案
看来问题可以追溯到熊猫源代码。这最终可能是 pandas 中的一个错误,该错误是由方法中意外使用BytesIO
对象所揭示的to_pickle
。我设法使用以下代码在最小可重现示例中规避了该问题,该代码使用模块中的dump
方法pickle
:
import pandas as pd
import numpy as np
import io
from pickle import dump
df = pd.DataFrame(np.random.randint(0,100,size=(4,4)))
buffer = io.BytesIO()
dump(df, buffer)
buffer.seek(0)
print(buffer.closed)
现在打印语句打印False
并且BytesIO
可以访问流数据。
推荐阅读
- swift - 如何将从 Firestore 检索到的时间戳值转换为 Date()?
- python - pyttsx3 ModuleNotFoundError:没有名为“pythoncom”的模块
- python - 如何删除 PixelArray 的元素
- django - 在 django 中使用“ImageKit”对已关闭文件进行 I/O 操作
- arrays - 在 Shell 脚本中将 SED Commnd 的字符串输出存储在数组中
- python - 无法通过 loaddata 将 JSON Postgresql 数据库备份上传到新的 Django Heroku 应用程序
- c# - 有人可以解释为什么会发生此错误
- .net - ML.NET:使用 GUID 作为 ID 的推荐
- kubernetes - 如何识别谁在 Kubernetes 中编辑了 yaml 或属性文件?
- apache-kafka - Spring cloud stream kafka binder 连接到 docker-compose kafka