Julia 缺失值的表示和处理

Julia语言想在数据分析领域分一杯羹还需要做很多的事情,其中一个事情就算对缺失值的处理。在数据分析中,观测样本存在缺失值是非常常见的,如果一个分析工具缺少应对机制,那么这个工具用起来会磕磕绊绊。

R语言的缺失值处理

R语言自上个世纪90年代起步,发展历史较长,所以对缺失值的处理机制比较完善。

> a <- c(1,NA,2,3,NA)
> a
[1]  1 NA  2  3 NA
> a+1
[1]  2 NA  3  4 NA
> mean(a)
[1] NA
> mean(a,na.rm = T)
[1] 2

常见的数据结构是dataframe,那么在这类数据中存在缺失值该如何处理?

R的处理还是很便捷的,具体代码如下。

> df <- data.frame(a,b=LETTERS[1:5])
> df
   a b
1  1 A
2 NA B
3  2 C
4  3 D
5 NA E
> mean(df[,"a"])
[1] NA
> mean(df[,"a"],na.rm = T)
[1] 2

原生的Julia

Julia原生对缺失值的表示和处理还不成熟。具体示例如下。

julia> a=[1 Nullable() 2 3 Nullable()]
1×5 Array{Nullable{Int64},2}:
 1  #NULL  2  3  #NULL

julia> a+1
WARNING: a::AbstractArray + b::Number is deprecated, use broadcast(+, a, b) instead.

julia> broadcast(+, a, 1)
ERROR: MethodError: no method matching +(::Nullable{Int64}, ::Int64)
Closest candidates are:
  +(::Any, ::Any, ::Any, ::Any...) at operators.jl:468
  +(::Complex{Bool}, ::Real) at complex.jl:275
  +(::Char, ::Integer) at char.jl:40
  ...

Nulls包的处理

现在是第三方包Nulls.jl来表示和处理缺失值。

julia> using Nulls
julia> a=[1 null 2 3 null]
1×5 Array{Union{Nulls.Null, Int64},2}:
 1  null  2  3  null

julia> a+1
1×5 Array{Any,2}:
 2  null  3  4  null

julia> mean(a)
null

这样,Julia对缺失值的表示和处理前进了一大步。不过,在R语言中NULL是表示空,NA是表示缺失值。

上面对含有缺失值的a向量求均值,结果为空。目前mean函数还没有对Null类型进行处理。

help?> mean
search: mean mean! median median! RemoteChannel SegmentationFault macroexpand @macroexpand @macroexpand1 module_parent

  mean(f::Function, v)

  Apply the function f to each element of v and take the mean.

  julia> mean(√, [1, 2, 3])
  1.3820881233139908

  julia> mean([√1, √2, √3])
  1.3820881233139908

  mean(v[, region])

  Compute the mean of whole array v, or optionally along the dimensions in region.

  | Note
  |
  |  Julia does not ignore NaN values in the computation. For applications requiring the handling of missing
  |  data, the DataArrays.jl package is recommended.

所以只能如下操作。Nulls.skip函数是由Nulls包提供。

julia>  mean(Nulls.skip(a))
2.0

现在最新的DataFrames也转为Nulls包的方法来表示和处理缺失值。

julia> using DataFrames
julia> df = DataFrame(A = [1, null, 2, 3, null], B = ["a", "b", "c", "d", "e"])
5×2 DataFrames.DataFrame
│ Row │ A    │ B │
├─────┼──────┼───┤
│ 1   │ 1    │ a │
│ 2   │ null │ b │
│ 3   │ 2    │ c │
│ 4   │ 3    │ d │
│ 5   │ null │ e │

julia> df[:A]
5-element Array{Union{Nulls.Null, Int64},1}:
 1
  null
 2
 3
  null

julia> mean(df[:A])
null

julia> mean(Nulls.skip(df[:A]))
2.0

个人的猜想是等Julia自身或者第三方对缺失值的表示方法成熟稳定后,一些涉及处理可能出现缺失值的对象的函数应该增写方法(见Julia手册的Methods章节),以更简洁的方式处理此类对象。目前采用Nulls.skip方法应该不是长久之计。

进一步阅读

  1. Replace Nullable{T} with Union{Some{T}, Void}
  2. The fate of Nullable

版本信息

R version 3.4.2 (2017-09-28) -- "Short Summer"

Julia
Version 0.7.0-DEV.2098 (2017-10-10 11:37 UTC)
Commit 546a801260* (16 days old master)
- DataFrames                    0.10.1+            master
- Nulls                         0.1.2+             master

其中Julia的第三方包是直接手动Clone最新的代码。

=========

补充:

现在Version 0.7.0-DEV.3095 (2017-12-19 01:41 UTC)中,missing已经成为Julia内置类型。原先的Nulls包也更名为Missings。

这样Julia更加适合统计与数据分析的场景。

# Version 0.7.0-DEV.3095 (2017-12-19 01:41 UTC)
julia> missing
missing

julia> missing + 1
missing

julia> true | missing
true

julia> false | missing
missing

julia> false & missing
false

julia> true & missing
missing

julia> sum([1,2,3,missing])
missing

julia> sum(skipmissing([1,2,3,missing]))
6
    原文作者:数据挖掘
    原文地址: https://juejin.im/entry/5b712358518825611c25b0dc
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞