如何在Julia中转换DataFrame时跳过缺失值

时间:2019-05-09 10:41:21

标签: dataframe julia missing-data

我想转换Julia DataFrames.DataFrame中的列中的每个元素,但是这样做会跳过缺少的值(让它们原样保留在表中)。

作为一个简单的示例,我们可以通过以下方式做到这一点:

using DataFrames, DataFramesMeta

@linq DataFrame(mode=[1,2,missing]) |>
transform(
    mode = map(x->(if x === missing missing elseif x in ([0:5...]) x+1 else missing end), :mode)
)

但是它看起来或多或少地混乱。会不会有更优雅或更简洁的方式?

我阅读了Query.jl和DataFramesMeta.jl文档,希望找到一种不必显式跳过缺失值的方法。

编辑: 我认为以下是我能想到的最好的方法:

using DataFrames, DataFramesMeta, DataValues

skipmap(f, c) = map(x->(if x===missing missing else f(x) end), c)

@linq DataFrame(mode=[1,2,missing]) |>
transform(
    mode = skipmap(x->if x in ([0:5...]) x+1 else x end, :mode)
)

我认为,如果map()以接受第三个参数y的方式扩展(因此map(f,c,y))并在数组中包含属于y的那些元素时将其保持完整,那将是很好的。

1 个答案:

答案 0 :(得分:4)

由DataFrames.jl导出的

passmissing可以满足您的需求。 例如,您可以使用这种单线:

julia> passmissing(x -> x + (x in 0:5)).([1,2,missing,4,5,6])
6-element Array{Union{Missing, Int64},1}:
 2
 3
  missing
 5
 6
 6

此外,您可以将广播用作+,如果您通过inmissing函数会隐式返回missing,例如:

julia> x = [1,2,missing,4,5,6]
6-element Array{Union{Missing, Int64},1}:
 1
 2
  missing
 4
 5
 6

julia> x .+ in.(x, Ref(0:5))
6-element Array{Union{Missing, Int64},1}:
 2
 3
  missing
 5
 6
 6

julia> (v -> v + in(v, 0:5)).(x)
6-element Array{Union{Missing, Int64},1}:
 2
 3
  missing
 5
 6
 6