如何按条件对Julia DataFrame进行子集化,其中列具有缺失值

9
这似乎是一件非常简单的事情,但我却做不到。
我在Julia中有一个数据框DataFrame df,其中一列的类型为Array{Union{Missing, Int64},1}。该列中的值为:[missing, 1,2]。我想要的只是对数据框DataFrame 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查询来获得所需结果,但这似乎有些麻烦。
1个回答

15

如何进行行子集筛选

解决问题的方法有两种:

  1. 使用 isequal 替换 ==,因为 == 实现了三值逻辑。因此,只需写其中一个即可:
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] 是一个有效的索引。对于 DataFrame,当 i 是整数时,df[i] 不允许,因为判断会对用户来说太令人困惑(因为它与数组的存储模式有关,而与 DataFrame 不同)。但是,如果 iCartesianIndex,则允许编写 df[i](因为这是明确的)。我猜这不是您正在寻找的内容。

有关索引 DataFrame 的所有规则均在此处详细描述。此外,在JuliaCon 2020期间,将会举行一个研讨会,详细讨论 DataFrames.jl 中的索引设计(它是如何工作的,为什么要这样工作,以及内部实现方式)。


1
非常感谢!这非常有帮助。对于像我这样试图从Python转换的数据科学家来说,这些基本任务的简要解释将是巨大的帮助。非常感谢完整的讨论! - Savage Henry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接