无法过滤从箭头表创建的 DataFrame

Kob*_*bst 4 dataframe julia apache-arrow

我在 julia 中有以下函数,用于读取 Arrow 文件(使用 Arrow.jl)以从磁盘读取数据并处理它:

function getmembershipsdays(fromId, toId)
  memberships = Arrow.Table("HouseholdMemberships.arrow") |> DataFrame
  filter!([:IndividualId] => id -> id >= fromId && id <= toId, memberships)
  ...
end

> Error: ERROR: LoadError: MethodError: no method matching
> deleteat!(::Arrow.Primitive{Int64,Array{Int64,1}}, ::Array{Int64,1})

The DataFrame has the following structure:
123226x10 DataFrame
Row | MembershipId | IndividualId | HouseholdId | ...
    | Int64        | Int64        | Int64       |
Run Code Online (Sandbox Code Playgroud)

函数中用于单步执行 Dataframe 的其余代码有效,但如果添加过滤条件,则会出现此错误。就好像 Dataframe 列没有转换为底层的 julia 类型。

如果我做

m = filter([:IndividualId] => id -> id >= fromId && id <= toId, memberships)
Run Code Online (Sandbox Code Playgroud)

然后就可以了。如何就地过滤?

Bog*_*ski 6

您正在使用内存映射,这意味着您无法DataFrame就地调整从 Arrow.jl 源创建的大小。这是您为从 Arrow 源超快速零复制创建数据帧而必须付出的成本。

为什么要这样设计呢?

  1. 通常,您只读取数据帧(而不改变它们)——在这种情况下,您可能希望节省复制数据的成本(尤其是对于非常大的数据集)。
  2. 使用 DataFrames.jl 中的复制函数来执行复制非常容易(例如在示例中替换filter!为)。filter

请参阅https://bkamins.github.io/julialang/2020/11/06/arrow.html了解更多示例(特别是 - 如何避免使用IO源而不是文件名作为源进行内存映射)。

附言。请注意,id >= fromId && id <= toId可以直接写为fromId <= id <= toId