按没有 "missing" 值的行过滤 DataFrame

Filter DataFrame by rows which have no "missing" value

我有一个可能包含缺失值的 DataFrame,我想过滤掉所有至少包含一个缺失值的行,所以从这个

DataFrame(a = [1, 2, 3, 4], b = [5, missing, 7, 8], c = [9, 10, missing, 12])
4×3 DataFrame
 Row │ a      b        c
     │ Int64  Int64?   Int64?
─────┼─────────────────────────
   1 │     1        5        9
   2 │     2  missing       10
   3 │     3        7  missing
   4 │     4        8       12

我想要类似的东西

 Row │ a      b        c
     │ Int64  Int64?   Int64?
─────┼─────────────────────────
   1 │     1        5        9
   4 │     4        8       12

理想情况下,会有一个过滤函数,我可以将每一行传递给一个 lambda,然后执行 collectfindfirst 的组合等等,但我不知道如何将 lambda 传递给 subset@subset(来自 DataFramesMeta),因为我不仅有三列,还有 200 多个。

好的,这似乎行得通,但我将保留它以征求更多建议。

DataFrame(collect(filter(r -> nothing .== findfirst(collect(ismissing.(collect(r)))), eachrow(data[:, before_qs]))))

按照@Antonello 所说的,您可以使用 dropmissing 来完成。您有三个选择:

  • dropmissing:创建一个新的数据框,其中包含缺失值的删除行;
  • dropmissingview=true 创建源数据框的视图,其中包含缺失值的删除行;
  • dropmissing! 就地删除具有缺失值的行。

默认情况下会考虑所有列,但您可以更改它并传递一个列选择器来指定要包含在检查中的列。

最后,默认情况下,在删除具有缺失值的行后,列将更改其 eltype 以不允许缺失值,但您可以通过传递 disallowmissing=false 来更改此行为,在这种情况下它们仍然允许他们。

以下是使用 subsetismissing 执行过滤的方法:

julia> subset(df, All() .=> ByRow(!ismissing))
2×3 DataFrame
 Row │ a      b       c
     │ Int64  Int64?  Int64?
─────┼───────────────────────
   1 │     1       5       9
   2 │     4       8      12

(我正在使用 DataFrames.jl 中的标准 select

或者如果你有一个非常宽的数据框(比如数千列):

subset(df, AsTable(All()) => ByRow((x -> all(!ismissing, x))∘collect))

(这是一种针对宽表的快速按行聚合优化的特殊语法)