You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在使用collect加载Parquet文件前对其进行随机抽样?

解决大Parquet数据集的前置随机抽样问题

嘿,我完全懂你的困扰——直接把超大Parquet数据集用collect()拉进R内存,简直是在给会话崩溃挖坑,而平时用惯的dplyr抽样函数又没法直接用在Arrow Dataset上。别慌,这里有几个靠谱的解决方案:

方案一:用Arrow支持的随机函数做比例抽样

Arrow的Dataset支持SQL风格的rand()函数,我们可以生成0到1之间的随机数,筛选出随机数小于抽样比例的行,实现近似随机抽样。这种方法不需要提前知道总行数,适合大数据集:

library(arrow)
library(dplyr)

# 打开Parquet数据集
ds <- open_dataset("~/mtcars")

# 比如抽取10%的样本,你可以根据需求调整比例
sample_ratio <- 0.1
sampled_data <- ds %>%
  filter(rand() < !!sample_ratio) %>%
  collect()

如果需要固定数量的样本,你可以先估算数据集总行数(用ds %>% count(),这个操作不会加载全量数据),再算出对应的抽样比例,或者在抽样后用head(n=3)调整数量。

方案二:用官方的dataset_sample()函数(Arrow 11.0.0+)

从Arrow 11.0.0版本开始,官方新增了dataset_sample()函数,专门针对Dataset做随机抽样,精准又省心:

library(arrow)

ds <- open_dataset("~/mtcars")
# 直接抽取3条样本
sampled_ds <- dataset_sample(ds, n = 3)
# 加载抽样后的结果到R内存
collect(sampled_ds)

如果你的Arrow版本低于11.0.0,建议先升级包,这个方法是最推荐的官方解决方案。

方案三:分块抽样(超大规模数据集专属)

如果你的Parquet是分块存储的(大部分大数据场景都是),可以先随机选部分分块,再在分块内抽样,进一步降低内存压力:

library(arrow)
library(dplyr)

ds <- open_dataset("~/mtcars")
# 获取所有分块文件的路径
all_chunks <- ds$files
# 随机选10%的分块(比例可以调整)
selected_chunks <- sample(all_chunks, size = floor(length(all_chunks)*0.1))
# 打开选中的分块,再用常规抽样函数处理
sampled_data <- open_dataset(selected_chunks) %>%
  slice_sample(n = 3) %>%
  collect()

为啥之前的方法行不通?

你之前试的slice_sample、slice都是为内存中的数据框设计的,不支持Arrow的Dataset对象——毕竟Dataset是存在磁盘上的,没有加载到内存,没法直接用行号定位;而row_number()在Dataset里也没法用,因为分块存储的特性,Arrow没法提前知道整个数据集的行号顺序。

内容的提问来源于stack exchange,提问作者Dan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 13:57:28