【发布时间】:2021-10-19 12:08:57
【问题描述】:
我查看了希望满足我需求的标准文档(Apache Arrow 和 Pandas),但我似乎无法弄清楚。
我最了解Python,所以我想用Python,但这不是一个严格的要求。
问题
我需要将 Parquet 文件从一个位置(一个 URL)移动到另一个位置(一个 Azure 存储帐户,在本例中使用 Azure 机器学习平台,但这与我的问题无关)。
这些文件太大而不能简单地执行pd.read_parquet("https://my-file-location.parquet"),因为这会将整个内容读入一个对象。
期待
我认为必须有一种简单 的方法来创建文件对象并逐行流式传输该对象——或者可能是逐列块。类似的东西
import pyarrow.parquet as pq
with pq.open("https://my-file-location.parquet") as read_file_handle:
with pq.open("https://my-azure-storage-account/my-file.parquet", "write") as write_filehandle:
for next_line in read_file_handle{
write_file_handle.append(next_line)
我知道这会有点不同,因为 Parquet 主要是为了以柱状方式访问。也许我会传递某种配置对象来指定感兴趣的列,或者可以在一个块中抓取多少行或类似的东西。
但关键的期望是 有一种方法可以访问 parquet 文件而不会将其全部加载到内存中。我该怎么做?
FWIW,我确实尝试使用 Python 的标准 open 函数,但我不确定如何将 open 与 URL 位置和字节流一起使用。如果可以仅通过 open 执行此操作并跳过任何特定于 Parquet 的内容,那也可以。
更新
一些 cmets 建议使用类似 bash 的脚本,例如 here。如果没有别的,我可以使用它,但这并不理想,因为:
- 我宁愿将这一切保存在一个完整的语言 SDK 中,无论是 Python、Go 还是其他任何东西。如果解决方案移动到带有管道的 bash 脚本中,则需要外部调用,因为最终解决方案不会完全由 bash、Powershell 或任何脚本语言编写。
- 我真的很想利用 Parquet 本身的一些好处。正如我在下面的评论中提到的,Parquet 是列式存储。因此,如果我有一个 11 亿行和 100 列的“数据框”,但我只关心 3 列,我希望能够只下载这 3 列,从而节省大量时间和金钱。
【问题讨论】:
-
好吧,我没有使用 S3。而且,更一般地说,我不想依赖另一个可能广为人知但仍未像 HTTPS 那样完全通用的文件系统。所以我不想使用 S3、Databricks 的 DBFS 或 Azure 的 DFS 等。
-
另外,需要明确的是,这个问题专门针对 Parquet。我假设有两件事:(1)如果我把它当作一个纯二进制文件并以某种方式流式传输它,这应该可以正常工作。所以@BeChillerToo 提到的
curl答案应该有效。 (2) 因为它是 Parquet,所以我应该具有能够在流式传输时即时进行一些简单处理的优势。例如,能够抓取感兴趣的列的子集而不是整个对象来存储。我希望这实际上可以根据要求完成,因此避免了不必要的网络 I/O。 -
如果你想在运行中进行处理,这会大大改变微积分;将其视为纯二进制可能会更快,甚至可能更快,但仅适用于没有处理的直接副本