如何进行行子集筛选
解决问题的方法有两种:
- 使用
isequal
替换 ==
,因为 ==
实现了三值逻辑。因此,只需写其中一个即可:
df[isequal.(df.col,2), :]
filter(:col => isequal(2), df)
filter!(:col => isequal(2), df)
- 如果您想使用
==
,请在其上方使用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.col
或 df."col"
(如果您在列名中有像空格这样的字符,则通常使用第二种方式)。这样,您就可以访问列 :col
而不需要复制它。使用索引编写此选择的等效方式是 df[!, :col]
。如果要复制列,请编写 df[:, :col]
。
一个附注 - 更高级的索引
实际上,在 Julia Base 中,如果 a
是一个数组(无论维数),则当 i
是整数或 CartesianIndex
时,a[i]
是一个有效的索引。对于 DataFrame
,当 i
是整数时,df[i]
不允许,因为判断会对用户来说太令人困惑(因为它与数组的存储模式有关,而与 DataFrame
不同)。但是,如果 i
是 CartesianIndex
,则允许编写 df[i]
(因为这是明确的)。我猜这不是您正在寻找的内容。
有关索引 DataFrame
的所有规则均在此处详细描述。此外,在JuliaCon 2020期间,将会举行一个研讨会,详细讨论 DataFrames.jl 中的索引设计(它是如何工作的,为什么要这样工作,以及内部实现方式)。