使用 apache 箭头读取一个 R 数据框中的分区镶木地板目录(所有文件)

Ale*_*ner 10 r rstudio parquet apache-arrow

如何使用箭头将分区的镶木地板文件读入 R(没有任何火花)

情况

  1. 使用 Spark 管道创建镶木地板文件并保存在 S3 上
  2. 使用 RStudio/RShiny 以一列作为索引读取以进行进一步分析

Parquet 文件结构

从我的 Spark 创建的镶木地板文件由几个部分组成

tree component_mapping.parquet/
component_mapping.parquet/
??? _SUCCESS
??? part-00000-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet
??? part-00001-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet
??? part-00002-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet
??? part-00003-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet
??? part-00004-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet
??? etc
Run Code Online (Sandbox Code Playgroud)

我如何将此 component_mapping.parquet 读入 R?

我试过的

install.packages("arrow")
library(arrow)
my_df<-read_parquet("component_mapping.parquet")
Run Code Online (Sandbox Code Playgroud)

但这因错误而失败

IOError: Cannot open for reading: path 'component_mapping.parquet' is a directory
Run Code Online (Sandbox Code Playgroud)

如果我只读取目录的一个文件,它就可以工作

install.packages("arrow")
library(arrow)
my_df<-read_parquet("component_mapping.parquet/part-00000-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet")
Run Code Online (Sandbox Code Playgroud)

但我需要加载所有内容才能对其进行查询

我在文档中发现的

在 apache 箭头文档 https://arrow.apache.org/docs/r/reference/read_parquet.htmlhttps://arrow.apache.org/docs/r/reference/ParquetReaderProperties.html 我发现有一些区域read_parquet() 命令的属性,但我无法让它工作,也找不到任何示例。

read_parquet(file, col_select = NULL, as_data_frame = TRUE, props = ParquetReaderProperties$create(), ...)
Run Code Online (Sandbox Code Playgroud)

如何正确设置属性以读取完整目录?

# should be this methods
$read_dictionary(column_index)
or
$set_read_dictionary(column_index, read_dict)
Run Code Online (Sandbox Code Playgroud)

帮助将不胜感激

Mat*_*ill 16

正如 @neal-richardson 在他的回答中提到的那样,在这方面已经做了更多的工作,并且使用当前的arrow软件包(我当前正在运行 4.0.0)这是可能的。

我注意到您的文件使用了快速压缩,这在安装之前需要特殊的构建标志。(此处安装文档:https ://arrow.apache.org/docs/r/articles/install.html )

Sys.setenv("ARROW_WITH_SNAPPY" = "ON")
install.packages("arrow",force = TRUE)
Run Code Online (Sandbox Code Playgroud)

DatasetAPI 通过多文件数据集实现您正在寻找的功能。虽然该文档尚未包含各种示例,但它确实提供了一个明确的起点。https://arrow.apache.org/docs/r/reference/Dataset.html

下面的示例显示了从给定目录读取多文件数据集并将其转换为内存中 R 数据帧的最小示例。该 API 还支持过滤条件和选择列的子集,尽管我仍在尝试自己找出语法。

library(arrow)

## Define the dataset
DS <- arrow::open_dataset(sources = "/path/to/directory")
## Create a scanner
SO <- Scanner$create(DS)
## Load it as n Arrow Table in memory
AT <- SO$ToTable()
## Convert it to an R data frame
DF <- as.data.frame(AT)
Run Code Online (Sandbox Code Playgroud)


Ale*_*ner 9

解决方案:使用箭头将本地文件系统中的分区镶木地板文件读取到 R 数据帧中

因为我想避免在 RShiny 服务器上使用任何 Spark 或 Python,所以我不能使用其他库,如sparklyr,SparkRreticulate以及dplyr如何在 R 中读取 Parquet 并将其转换为 R DataFrame 中所述?

我现在解决了我的任务,你的建议使用arrow连同lapplyrbindlist

my_df <-data.table::rbindlist(lapply(Sys.glob("component_mapping.parquet/part-*.parquet"), arrow::read_parquet))
Run Code Online (Sandbox Code Playgroud)

期待 apache 箭头功能可用,谢谢


Nea*_*son 6

读取文件目录不是通过为(单个)文件读取器设置选项可以实现的。如果内存不成问题,今天您可以lapply/ mapover 目录列表和rbind/bind_rows进入单个 data.frame。可能有一个purrr函数可以干净利落地做到这一点。在对文件的迭代中,如果您只需要一个已知的数据子集,您还可以选择/过滤每个文件。

在 Arrow 项目中,我们正在积极开发一个多文件数据集 API,它可以让你做你想做的事情,以及将行和列选择下推到单个文件等等。敬请关注。

  • 有多种方法可以在 R 中并行化文件读取,只是目前尚未纳入“arrow”包中。如果您希望将其内置到箭头中,请稍后再回来查看,它即将推出。 (2认同)

Ale*_*ner 5

解决方案:使用箭头将分区 parquet 文件从 S3 读取到 R 数据帧中

由于我现在花了很长时间才找到解决方案,而且我无法在网络上找到任何内容,所以我想分享这个关于如何从 S3 读取分区镶木地板文件的解决方案

library(arrow)
library(aws.s3)

bucket="mybucket"
prefix="my_prefix"

# using aws.s3 library to get all "part-" files (Key) for one parquet folder from a bucket for a given prefix pattern for a given component
files<-rbindlist(get_bucket(bucket = bucket,prefix=prefix))$Key

# apply the aws.s3::s3read_using function to each file using the arrow::read_parquet function to decode the parquet format
data <- lapply(files, function(x) {s3read_using(FUN = arrow::read_parquet, object = x, bucket = bucket)})
  
# concatenate all data together into one data.frame
data <- do.call(rbind, data)
Run Code Online (Sandbox Code Playgroud)

真是一团糟,但它有效。@neal-richardson 有没有使用箭头直接从 S3 读取?我在 R 的文档中找不到任何内容