首页 > 解决方案 > 使用缺失值初始化列并将数据框的另一列复制+转换为初始化列

问题描述

我在文件中有一个凌乱的列csv(数据框的 A 列)。

using CSV, DataFrames
df = DataFrame(A = ["1", "3", "-", "4", missing, "9"], B = ["M", "F", "R", "G", "Z", "D"])

我想做的是:

  1. 将整数从字符串转换为数字(例如Float64
  2. 将字符串转换"-"missing

该策略是首先定义一个新的列向量填充缺失

df[:C] = fill(missing, size(df)[1])

然后使用 for 循环执行 2 次转换

for i in 1:size(df)[1]
    if df[:A][i] == "-"
        continue
    else
        df[:C][i] = parse(Float64,df[:A][i])
    end
end

但是,在查看时,df[:C]我有一列只填充了缺失。我究竟做错了什么?

标签: dataframejulianamissing-data

解决方案


您的代码存在几个问题,但首先让我展示如何编写此转换:

df.C = passmissing(parse).(Float64, replace(df.A, "-"=>missing))

这不是最有效的方法,但很容易推理。

使用循环的实现可能如下所示:

df.C = similar(df.A, Union{Float64, Missing});

for (i, a) in enumerate(df.A)
    if !ismissing(a) && a != "-"
        df.C[i] = parse(Float64, a)
    else
        df.C[i] = missing
    end
end

请注意,similar默认情况下将填充df.Cwithmissing以便else可以删除该部分,但是没有记录此行为,因此编写它更安全。

您还可以使用理解:

df. C = [ismissing(a) || a == "-" ? missing : parse(Float64, a) for a in df.A]

现在,要修复您的代码,您可以编写:

# note a different initialization
# in your code df.C allowed only values of Missing type and disallows of Float64 type
df.C = Vector{Union{Float64, Missing}}(missing, size(df, 1))

for i in 1:size(df)[1]
    # note that we need to handle missing value and "=" separately
    if ismissing(df.A[i]) || df.A[i] == "-"
        continue
    else
        df.C[i] = parse(Float64,df.A[i])
    end
end

df.C最后请注意,与访问数据帧中的列相比,写入更可取df[:C](目前两者是等效的,但将来可能会改变)。


推荐阅读