Python 3:如何在不保存在磁盘上的情况下将 pandas 数据帧作为 csv 流上传?
Posted
技术标签:
【中文标题】Python 3:如何在不保存在磁盘上的情况下将 pandas 数据帧作为 csv 流上传?【英文标题】:Python 3: How to upload a pandas dataframe as a csv stream without saving on disc? 【发布时间】:2018-06-09 19:35:36 【问题描述】:我想将 pandas 数据帧作为 csv 文件上传到服务器,而不将其保存在光盘上。有没有办法创建一个或多或少的“假 csv”文件来伪装成真实文件?
下面是一些示例代码: 首先,我从 sql 查询中获取数据并将其存储为数据框。 在upload_ga_data 函数中,我想要一些具有这种逻辑的东西
media = MediaFileUpload('df',
mimetype='application/octet-stream',
resumable=False)
完整示例:
from __future__ import print_function
from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient.errors import HttpError
from apiclient.http import MediaFileUpload
import pymysql
import pandas as pd
con = x
ga_query = """
SELECT XXXXX
"""
df = pd.read_sql_query(ga_query,con)
df.to_csv('ga_export.csv', sep=',', encoding='utf-8', index = False)
def upload_ga_data():
try:
media = MediaFileUpload('ga_export.csv',
mimetype='application/octet-stream',
resumable=False)
daily_upload = service.management().uploads().uploadData(
accountId=accountId,
webPropertyId=webPropertyId,
customDataSourceId=customDataSourceId,
media_body=media).execute()
print ("Upload was successfull")
except TypeError as error:
# Handle errors in constructing a query.
print ('There was an error in constructing your query : %s' % error)
【问题讨论】:
【参考方案1】:使用stream 可以实现所需的行为:
创建一个或多或少的“假 csv”文件,伪装成真实文件
Python 使 File Descriptor(使用 open
)和 Stream(使用 io.StringIO
)表现相似。那么任何可以使用文件描述符的地方也可以使用字符串流。
创建文本流最简单的方法是使用 open(),可选 指定编码:
f = open("myfile.txt", "r", encoding="utf-8")
内存中的文本流也可用作 StringIO 对象:
f = io.StringIO("some initial text data")
文本流API在文档中有详细描述 TextIOBase.
在 Pandas 中,您可以使用在其 signature 中包含 path_or_buf
参数的任何 function 来执行此操作,例如 to_csv
:
DataFrame.to_csv(
path_or_buf
=None, sep=', ', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, mode='w', encoding=None, compression=None, quoting=None, quotechar='"', line_terminator='\n', chunksize=None, tupleize_cols=None, date_format=None, doublequote=True, escapechar=None, decimal='.')
以下代码将 CSV 格式的虚拟 DataFrame 导出为字符串流(不是物理文件,内存中的八位字节流):
import io
import pandas as pd
df = pd.DataFrame(list(range(10)))
stream = io.StringIO()
df.to_csv(stream, sep=";")
当您想访问流内容时,只需发出:
>>> stream.getvalue()
';0\n0;0\n1;1\n2;2\n3;3\n4;4\n5;5\n6;6\n7;7\n8;8\n9;9\n'
无需使用真实文件即可返回内容。
【讨论】:
优秀、简单的解释和扎实的演示——谢谢! 我尝试使用http.MediaIoBaseUpload(stream.getvalue(), mimetype=mimetype, resumable=True)
上传,但它会引发 FileNotFoundError: [Errno 2] No such file or directory
错误。我是否遗漏了某些内容,或者该流是否真的不适用于上传?
@AlphaCR 只是传递流。不返回被解释为文件路径的值。
只传递流只会导致TypeError: expected str, bytes or os.PathLike object, not _io.StringIO
。也许是因为其他原因?
没有minimal reproducible example 很难说。但是您的错误表明该对象不接受 StringIO 并期望字节。也许你会通过io.BytesIO
对象获得成功。以上是关于Python 3:如何在不保存在磁盘上的情况下将 pandas 数据帧作为 csv 流上传?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不将 csv 保存到磁盘的情况下将 csv 格式的数据从内存发送到数据库?
如何在不写入磁盘的情况下将 XML 从 Delphi 传递到 C#?
如何在不知道编码的情况下将字节写入 Python 3 中的文件?