读取 S3 实木复合地板的最后 N 行 table

Read last N rows of S3 parquet table

如果我应用讨论的内容 将 S3 buck 中的镶木地板文件读取到 pandas 数据帧,特别是:

import pyarrow.parquet as pq
import s3fs
s3 = s3fs.S3FileSystem()

pandas_dataframe = pq.ParquetDataset('s3://your-bucket/', filesystem=s3).read_pandas().to_pandas()

当 table 随着时间的推移变得越来越大,我需要定期进行此检索时,我只想将最后 N 行读入数据框。这可能吗?

不,仅使用 S3 是不可能的。 S3 是一个对象存储,它让您仅存储、检索、更新等 'whole' 个对象,即文件。

话虽如此,您应该看看 Athena,这是一种无服务器查询服务,可以使用 Standard SQL 轻松分析存储在 Amazon S3 中的大量数据。它应该让你做你想做的事。

最好的,斯特凡

是的,这完全有可能。 S3 允许部分对象读取。 Parquet 文件允许基于行组进行部分读取(并且 pyarrow 公开了此功能)。此外,如果您有多个文件(无论文件格式如何),pyarrow 允许部分读取。但是,这些方法会对输入文件的创建方式提出一些要求(请参阅底部)。

简单的方法

最简单的方法是使用较新的 datasets API(它本身值得一读,并废弃了您引用的一些问题)并在某种列上进行过滤。

import pyarrow.dataset as ds
from datetime import datetime, timedelta

two_days_ago = datetime.now() - timedelta(days=2)
dataset = ds.dataset('s3://your-bucket').to_table(filter=ds.field('sample_date') > two_days_ago)

pyarrow 数据集 API 支持“下推过滤器”,这意味着过滤器被下推到 reader 层。如果 reader 能够减少使用过滤器读取的数据量,那么它会的。对于像这样的简单过滤器,parquet reader 能够通过首先查看行组元数据来优化读取,行组元数据应该有一个“统计”部分,其中包含每列的 min/max。

但是,这并不完全是“最后 N 行”,因为它需要您制作某种过滤器。如果您可以完全控制数据,那么您可以创建一个 row_num 列。如果您知道总行数(您可以单独存储或通过元数据访问,请参见下文),则可以对其创建过滤器。)

稍微不那么简单的方法

或者,您可以使用具有 metadata 属性的 ParquetFile。访问它只会触发对元数据本身(不是整个文件)的读取。从这里您可以获得一些信息,例如文件中有多少行组以及它们包含多少行。您可以使用它来确定您需要多少行组,您可以使用 read_row_groupread_row_groups 来访问这些行组(这不会触发完整的文件读取)。

这些解决方案都不理想。第一个选项要求您对数据有更多的控制权,第二个选项要求您自己做很多工作。 Arrow 项目正在努力简化这种操作(例如,参见 ARROW-3705 )。但是,此答案仅基于今天可用的功能。

最后一点:所有这些方法(甚至是 Arrow 开发的任何未来方法)都需要将数据存储为多个文件或多个行组。如果您将一个巨大的文件存储为单个行组,那么就没有什么可以做的了。 Parquet 不支持部分行组读取。