nanoarrow 的目標是為 Arrow C Data 和 Arrow C Stream 介面提供最精簡且實用的綁定,並使用 nanoarrow C 程式庫。
安裝
您可以從 CRAN 安裝已發布版本的 nanoarrow,使用:
install.packages("nanoarrow")
您可以從 GitHub 安裝開發版本的 nanoarrow,使用:
# install.packages("remotes")
remotes::install_github("apache/arrow-nanoarrow/r")
如果您可以載入套件,那就沒問題了!
範例
Arrow C Data 和 Arrow C Stream 介面包含三個結構:ArrowSchema
代表陣列的資料類型、ArrowArray
代表陣列的值,以及 ArrowArrayStream
,代表零或多個具有通用 ArrowSchema
的 ArrowArray
。所有這三個都可以使用 nanoarrow R 套件由 R 物件包裝。
結構描述
使用 infer_nanoarrow_schema()
取得對應於給定 R 向量類型的 ArrowSchema 物件;使用 as_nanoarrow_schema()
從其他資料類型表示形式(例如,arrow R 套件 DataType
,如 arrow::int32()
)轉換物件;或使用 na_XXX()
函式來建構它們。
infer_nanoarrow_schema(1:5)
#> <nanoarrow_schema int32>
#> $ format : chr "i"
#> $ name : chr ""
#> $ metadata : list()
#> $ flags : int 2
#> $ children : list()
#> $ dictionary: NULL
as_nanoarrow_schema(arrow::schema(col1 = arrow::float64()))
#> <nanoarrow_schema struct>
#> $ format : chr "+s"
#> $ name : chr ""
#> $ metadata : list()
#> $ flags : int 0
#> $ children :List of 1
#> ..$ col1:<nanoarrow_schema double>
#> .. ..$ format : chr "g"
#> .. ..$ name : chr "col1"
#> .. ..$ metadata : list()
#> .. ..$ flags : int 2
#> .. ..$ children : list()
#> .. ..$ dictionary: NULL
#> $ dictionary: NULL
na_int64()
#> <nanoarrow_schema int64>
#> $ format : chr "l"
#> $ name : chr ""
#> $ metadata : list()
#> $ flags : int 2
#> $ children : list()
#> $ dictionary: NULL
陣列
使用 as_nanoarrow_array()
將物件轉換為 ArrowArray 物件
as_nanoarrow_array(1:5)
#> <nanoarrow_array int32[5]>
#> $ length : int 5
#> $ null_count: int 0
#> $ offset : int 0
#> $ buffers :List of 2
#> ..$ :<nanoarrow_buffer validity<bool>[0][0 b]> ``
#> ..$ :<nanoarrow_buffer data<int32>[5][20 b]> `1 2 3 4 5`
#> $ dictionary: NULL
#> $ children : list()
as_nanoarrow_array(data.frame(col1 = c(1.1, 2.2)))
#> <nanoarrow_array struct[2]>
#> $ length : int 2
#> $ null_count: int 0
#> $ offset : int 0
#> $ buffers :List of 1
#> ..$ :<nanoarrow_buffer validity<bool>[0][0 b]> ``
#> $ children :List of 1
#> ..$ col1:<nanoarrow_array double[2]>
#> .. ..$ length : int 2
#> .. ..$ null_count: int 0
#> .. ..$ offset : int 0
#> .. ..$ buffers :List of 2
#> .. .. ..$ :<nanoarrow_buffer validity<bool>[0][0 b]> ``
#> .. .. ..$ :<nanoarrow_buffer data<double>[2][16 b]> `1.1 2.2`
#> .. ..$ dictionary: NULL
#> .. ..$ children : list()
#> $ dictionary: NULL
您可以使用 as.vector()
或 as.data.frame()
來取回物件的 R 表示形式
array <- as_nanoarrow_array(data.frame(col1 = c(1.1, 2.2)))
as.data.frame(array)
#> col1
#> 1 1.1
#> 2 2.2
即使在 C 語言層級,ArrowArray 與 ArrowSchema 是不同的,但在 R 語言層級,我們會盡可能附加結構描述。您可以使用 infer_nanoarrow_schema()
存取附加的結構描述
infer_nanoarrow_schema(array)
#> <nanoarrow_schema struct>
#> $ format : chr "+s"
#> $ name : chr ""
#> $ metadata : list()
#> $ flags : int 0
#> $ children :List of 1
#> ..$ col1:<nanoarrow_schema double>
#> .. ..$ format : chr "g"
#> .. ..$ name : chr "col1"
#> .. ..$ metadata : list()
#> .. ..$ flags : int 2
#> .. ..$ children : list()
#> .. ..$ dictionary: NULL
#> $ dictionary: NULL
陣列串流
建立 ArrowArrayStream 最簡單的方法是從陣列列表或可以使用 as_nanoarrow_array()
轉換為陣列的物件列表建立
stream <- basic_array_stream(
list(
data.frame(col1 = c(1.1, 2.2)),
data.frame(col1 = c(3.3, 4.4))
)
)
您可以使用 $get_next()
方法從串流中提取批次。最後一個批次將傳回 NULL
。
stream$get_next()
#> <nanoarrow_array struct[2]>
#> $ length : int 2
#> $ null_count: int 0
#> $ offset : int 0
#> $ buffers :List of 1
#> ..$ :<nanoarrow_buffer validity<bool>[0][0 b]> ``
#> $ children :List of 1
#> ..$ col1:<nanoarrow_array double[2]>
#> .. ..$ length : int 2
#> .. ..$ null_count: int 0
#> .. ..$ offset : int 0
#> .. ..$ buffers :List of 2
#> .. .. ..$ :<nanoarrow_buffer validity<bool>[0][0 b]> ``
#> .. .. ..$ :<nanoarrow_buffer data<double>[2][16 b]> `1.1 2.2`
#> .. ..$ dictionary: NULL
#> .. ..$ children : list()
#> $ dictionary: NULL
stream$get_next()
#> <nanoarrow_array struct[2]>
#> $ length : int 2
#> $ null_count: int 0
#> $ offset : int 0
#> $ buffers :List of 1
#> ..$ :<nanoarrow_buffer validity<bool>[0][0 b]> ``
#> $ children :List of 1
#> ..$ col1:<nanoarrow_array double[2]>
#> .. ..$ length : int 2
#> .. ..$ null_count: int 0
#> .. ..$ offset : int 0
#> .. ..$ buffers :List of 2
#> .. .. ..$ :<nanoarrow_buffer validity<bool>[0][0 b]> ``
#> .. .. ..$ :<nanoarrow_buffer data<double>[2][16 b]> `3.3 4.4`
#> .. ..$ dictionary: NULL
#> .. ..$ children : list()
#> $ dictionary: NULL
stream$get_next()
#> NULL
您可以透過呼叫 as.data.frame()
或 as.vector()
將所有批次提取到 data.frame()
中
stream <- basic_array_stream(
list(
data.frame(col1 = c(1.1, 2.2)),
data.frame(col1 = c(3.3, 4.4))
)
)
as.data.frame(stream)
#> col1
#> 1 1.1
#> 2 2.2
#> 3 3.3
#> 4 4.4
在使用完串流後,您應盡快呼叫 release 方法。這樣可以讓串流的實作釋放它可能持有的任何資源(例如開啟的檔案),比起等待垃圾收集器清理物件,這是一種更可預測的方式。
與 arrow 套件整合
nanoarrow 套件為大多數 arrow 套件類型實作了 as_nanoarrow_schema()
、as_nanoarrow_array()
和 as_nanoarrow_array_stream()
。同樣地,它為 nanoarrow 物件實作了 arrow::as_arrow_array()
、arrow::as_record_batch()
、arrow::as_arrow_table()
、arrow::as_record_batch_reader()
、arrow::infer_type()
、arrow::as_data_type()
和 arrow::as_schema()
,因此您可以將等效的 nanoarrow 物件傳遞到許多 arrow 函式中,反之亦然。