【问题标题】:How to subset Julia DataFrame by condition, where column has missing values如何按条件对 Julia DataFrame 进行子集化,其中列缺少值
【发布时间】:2026-02-03 16:45:02
【问题描述】:

这看起来应该非常简单,但我无法完成。

我在 julia 有一个数据框 df,其中一列的类型为 Array{Union{Missing, Int64},1}

该列中的值为:[missing, 1, 2]

我只想对数据框 df 进行子集化,以仅查看与条件相对应的那些行,例如列等于 2 的位置。

我尝试过的 --> 结果:

df[df[:col].==2] --> MethodError: no method matching getindex

df[df[:col].==2, :] --> ArgumentError: invalid row index of type Bool

df[df[:col].==2, :col] --> BoundsError: attempt to access String (请注意,只执行df[!, :col] 会导致:1339-element Array{Union{Missing, Int64},1}: [...eliding output...],到目前为止我最喜欢的警告是 julia:Warning: getindex(df::DataFrame, col_ind::ColumnIndex) is deprecated, use df[!, col_ind] instead. 刚刚使用它似乎可以让我免于警告,但无论如何。)

这不可能像看起来那么难。

仅供参考,我可以通过using Query 获得我想要的内容,并针对子集数据进行多行 sql 查询,这似乎...很麻烦。

【问题讨论】:

    标签: dataframe conditional-statements julia subset


    【解决方案1】:

    如何进行行子集化

    有两种方法可以解决您的问题:

    1. 使用isequal 而不是==,因为== 实现3-valued logic。所以只需编写其中一个即可:
    df[isequal.(df.col,2), :] # new data frame
    filter(:col => isequal(2), df) # new data frame
    filter!(:col => isequal(2), df) # update old data frame in place
    
    1. 如果你想使用==,请在上面使用coalesce,例如:
    df[coalesce.(df.col .== 2, false), :] # new data frame
    

    与 DataFrames.jl 没有什么特别之处。索引在 Julia Base 中的工作方式相同:

    julia> x = [1, 2, missing]
    3-element Array{Union{Missing, Int64},1}:
     1
     2
      missing
    
    julia> x[x .== 2]
    ERROR: ArgumentError: unable to check bounds for indices of type Missing
    
    julia> x[isequal.(x, 2)]
    1-element Array{Union{Missing, Int64},1}:
     2
    

    (通常,您可以期望,在可能的情况下,DataFrames.jl 将与 Julia Base 保持一致;除了一些不可能的极端情况 - 主要区别在于 DataFrame 具有异构列元素这一事实类型,而 Julia Base 中的 Matrix 具有同质元素类型)

    如何做索引

    DataFrame 是一个二维对象。它有行和列。在 Julia 中,通常使用df[...] 表示法通过其维度中的位置访问对象。因此df[:col] 不是索引DataFrame 的有效方法。您正在尝试使用一个索引维度,同时需要指定行索引和列索引。您收到警告,因为您使用了无效的索引方法(在 DataFrames.jl 的下一版本中,此警告将消失,您只会收到错误)。

    实际上,您的示例 df[df[:col].==2] 说明了我们为什么不允许单维索引。在df[:col] 中,您尝试使用单维索引来对 进行子集化,但在外部df[df[:col].==2] 中,您希望使用单维索引对 进行子集化。

    从数据框中获取列的最简单方法是df.coldf."col"(如果列名中有空格等字符,通常使用第二种方法)。这样您就可以访问列:col 而无需复制它。使用索引编写此选择的等效方法是df[!, :col]。如果你想复制列写df[:, :col]

    附注 - 更高级的索引

    事实上,在 Julia Base 中,如果 a 是一个数组(任何维度),那么如果 i 是一个整数或 CartesianIndex,那么 a[i] 是一个有效索引。 df[i],其中i 是一个整数,对于DataFrame 是不允许的,因为如果我们想遵循 Julia Base 的约定(因为它与与DataFrame 不同的数组)。当iCartesianIndex 时,你可以写df[i](因为这是明确的)。我猜这不是你要找的东西。

    所有允许索引DataFrame 的规则都详细描述了here。此外,在JuliaCon 2020 期间,还将举办一个研讨会,在此期间,将详细讨论 DataFrames.jl 中的索引设计(它是如何工作的,为什么会这样工作,以及它是如何在内部实现的)。

    【讨论】:

    • 非常感谢!这非常有帮助。这些基本任务的简要解释器将对像我这样试图从 Python 学习的数据科学家提供巨大的帮助。感谢完整的讨论!
    最近更新 更多