我查看了我期望能够满足我的需求的标准文档(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)
Run Code Online (Sandbox Code Playgroud)
我知道它会有点不同,因为 Parquet 主要是为了以柱状方式访问。也许我会传递某种配置对象,它指定感兴趣的列,或者可以在一个块或类似的东西中抓取多少行。
但主要的期望是有一种方法可以访问 parquet 文件,而无需将其全部加载到内存中。我怎样才能做到这一点?
FWIW,我确实尝试过只使用 Python 的标准open函数,但我不确定如何使用openURL 位置和字节流。如果可以通过跳过open任何 Parquet 特定的内容来完成此操作,那也很好。
一些评论建议使用类似 bash 的脚本,例如这里。如果没有别的办法我可以使用这个,但它并不理想,因为:
很棒的帖子,基于 @Micah 的回答,我在其中投入了 2 美分,以防您不想阅读文档。一个小片段如下:
import pandas as pd
import numpy as np
from pyarrow.parquet import ParquetFile
# create a random df then save to parquet
df = pd.DataFrame({
'A': np.arange(10000),
'B': np.arange(10000),
'C': np.arange(10000),
'D': np.arange(10000),
})
df.to_parquet('./test/test')
# ****** below is @Micah Kornfield's answer ******
# 1. open parquet file
batch = ParquetFile('./test/test')
# 2. define generator of batches
record = batch.iter_batches(
batch_size=10,
columns=['B', 'C'],
)
# 3. yield pandas/numpy data
print(next(record).to_pandas()) # pandas
print(next(record).to_pydict()) # native python dict
Run Code Online (Sandbox Code Playgroud)
这是可能的,但需要一些工作,因为除了柱状 Parquet 之外,还需要一个架构。
大致的工作流程是:
打开parquet 文件进行读取。
然后使用iter_batches增量读回行块(您也可以传递要从文件中读取的特定列以节省 IO/CPU)。
然后你可以进一步改造每pa.RecordBatch一个iter_batches。完成第一批的转换后,您可以获得其架构并创建一个新的ParquetWriter。
对于每个转换后的批次调用write_table。您必须先将其转换为pa.Table.
关闭文件。
Parquet 需要随机访问,因此无法轻松地从 URI 进行流式传输(如果您通过HTTP FSSpec打开文件,pyarrow 应该支持它),但我认为您可能会在写入时被阻止。
| 归档时间: |
|
| 查看次数: |
14940 次 |
| 最近记录: |