【问题标题】:Julia | DataFrame | Replacing missing Values朱莉娅 |数据框 |替换缺失值
【发布时间】:2016-04-09 05:51:04
【问题描述】:

对于DataFrame 中的列,我们如何将missing 值替换为0.0

【问题讨论】:

  • 不喜欢df[:B]=convert(Array,df[:B],0.0) ?
  • @RezaAfzalan 我尝试使用这种方法,但是当我运行convert(Array,df_of_names,"none") 时,它给出了一个错误提示MethodError: no method matching convert(::Type{Array}, ::DataFrames.DataFrame, ::String)。运行convert(Array,df_of_names) 工作正常。知道为什么会出现这个错误吗?

标签: dataframe julia


【解决方案1】:

有几种不同的方法可以解决这个问题(适用于 Julia 1.x):

Base.replace!

可能最简单的方法是使用来自基本 Julia 的 replace!replace。这是replace! 的示例:

julia> using DataFrames

julia> df = DataFrame(x = [1, missing, 3])
3×1 DataFrame
│ Row │ x       │
│     │ Int64⍰  │
├─────┼─────────┤
│ 1   │ 1       │
│ 2   │ missing │
│ 3   │ 3       │

julia> replace!(df.x, missing => 0);

julia> df
3×1 DataFrame
│ Row │ x      │
│     │ Int64⍰ │
├─────┼────────┤
│ 1   │ 1      │
│ 2   │ 0      │
│ 3   │ 3      │

但是,请注意,此时列x 的类型仍然允许缺失值:

julia> typeof(df.x)
Array{Union{Missing, Int64},1}

当打印出数据帧时,这也由列xInt64 后面的问号指示。您可以使用disallowmissing! (from the DataFrames.jl package):

julia> disallowmissing!(df, :x)
3×1 DataFrame
│ Row │ x     │
│     │ Int64 │
├─────┼───────┤
│ 1   │ 1     │
│ 2   │ 0     │
│ 3   │ 3     │

或者,如果您按如下方式使用replace(不带感叹号),那么输出将已经不允许缺失值:

julia> df = DataFrame(x = [1, missing, 3]);

julia> df.x = replace(df.x, missing => 0);

julia> df
3×1 DataFrame
│ Row │ x     │
│     │ Int64 │
├─────┼───────┤
│ 1   │ 1     │
│ 2   │ 0     │
│ 3   │ 3     │

Base.ismissing 与逻辑索引

您可以使用 ismissing 和逻辑索引来为数组中所有缺失的条目分配一个新值:

julia> df = DataFrame(x = [1, missing, 3]);

julia> df.x[ismissing.(df.x)] .= 0;

julia> df
3×1 DataFrame
│ Row │ x      │
│     │ Int64⍰ │
├─────┼────────┤
│ 1   │ 1      │
│ 2   │ 0      │
│ 3   │ 3      │

Base.coalesce

另一种方法是使用coalesce

julia> df = DataFrame(x = [1, missing, 3]);

julia> df.x = coalesce.(df.x, 0);

julia> df
3×1 DataFrame
│ Row │ x     │
│     │ Int64 │
├─────┼───────┤
│ 1   │ 1     │
│ 2   │ 0     │
│ 3   │ 3     │

DataFramesMeta

replacecoalesce 都可以与 DataFramesMeta.jl 包中的 @transform 宏一起使用:

julia> using DataFramesMeta

julia> df = DataFrame(x = [1, missing, 3]);

julia> @transform(df, x = replace(:x, missing => 0))
3×1 DataFrame
│ Row │ x     │
│     │ Int64 │
├─────┼───────┤
│ 1   │ 1     │
│ 2   │ 0     │
│ 3   │ 3     │
julia> df = DataFrame(x = [1, missing, 3]);

julia> @transform(df, x = coalesce.(:x, 0))
3×1 DataFrame
│ Row │ x     │
│     │ Int64 │
├─────┼───────┤
│ 1   │ 1     │
│ 2   │ 0     │
│ 3   │ 3     │

其他文档

【讨论】:

    【解决方案2】:

    自从 Julia 最近引入了 missing 属性以来,这是一个更短且更新的答案。

    using DataFrames
    df = DataFrame(A=rand(1:50, 5), B=rand(1:50, 5), C=vcat(rand(1:50,3), missing, rand(1:50))) ## Creating random 5 integers within the range of 1:50, while introducing a missing variable in one of the rows
    df = DataFrame(replace!(convert(Matrix, df), missing=>0)) ## Converting to matrix first, since replacing values directly within type dataframe is not allowed
    

    【讨论】:

    • 如果DataFrame 的所有列都具有相同的类型,则此答案非常好。如果不是这种情况,您将丢失所有类型信息,并且每列都有Any 类型。
    【解决方案3】:

    其他答案都很好。如果您是一个真正的速度迷,也许以下内容可能适合您:

    # prepare example
    using DataFrames
    df = DataFrame(A = 1.0:10.0, B = 2.0:2.0:20.0)
    df[ df[:A] %2 .== 0, :B ] = NA
    
    
    df[:B].data[df[:B].na] = 0.0 # put the 0.0 into NAs
    df[:B] = df[:B].data         # with no NAs might as well use array
    

    【讨论】:

      【解决方案4】:

      用一些NAs 创建df

      using DataFrames
      df = DataFrame(A = 1.0:10.0, B = 2.0:2.0:20.0)
      df[ df[:B] %2 .== 0, :A ] = NA
      

      你会在df中看到一些NA...我们现在将它们转换为0.0

      df[ isna(df[:A]), :A] = 0
      

      编辑=NaNNA。谢谢@Reza

      【讨论】:

        猜你喜欢
        • 2018-11-27
        • 2014-04-26
        • 1970-01-01
        • 2015-02-19
        • 1970-01-01
        • 1970-01-01
        • 2014-02-04
        • 2014-12-31
        • 2017-01-15
        相关资源
        最近更新 更多