在Julia中没有值的DataFrame列?

时间:2019-09-19 08:39:42

标签: julia

我试图了解DataFrames在Julia中的工作方式,我度过了艰难的时光。

我通常在Python中使用DataFrames-在每个模拟步骤中添加新列,并在每个行中填充值。

例如,我有一个包含输入数据的DataFrame:

using DataFrames

df = DataFrame( A=Int[], B=Int[] )
push!(df, [1, 10])
push!(df, [2, 20])
push!(df, [3, 30])

现在,假设我根据这些AB列进行计算,这些列生成带有DateTime对象的第三列C。但是并非所有行都生成DateTime对象,它们可以为null。

  1. 该用例在Julia中如何处理?
  2. 如何创建新的C列并在for r in eachrow(df)内分配值?
# Pseudocode of what I intend to do

df[! :C] .= nothing

for r in eachrow(df)
    if condition
        r.C = mySuperComplexFunctionThatReturnsDateTimeForEachRow()
    else
        r.C = nothing
    end
end

要给出可运行且具体的代码,让我们伪造条件和函数:

df[! :C] .= nothing

for r in eachrow(df)
    if r.A == 2
        r.C = Dates.now()
    else
        r.C = nothing
    end
end

2 个答案:

答案 0 :(得分:3)

执行此操作的有效模式是:

df.C = f.(df.A, df.B)

其中f是一个获取标量并基于标量计算输出的函数(即您的模拟代码),然后将需要从df中提取的列传递给标量,以执行计算。这样,Julia编译器将能够生成快速的(类型稳定的)本地代码。

在您的示例中,函数f将为ifelse,因此您可以编写:

df.C = ifelse.(df.A .== 2, Dates.now(), nothing)

还要考虑是否返回nothingmissing(它们在Julia中的解释不同:nothing表示不存在值,而missing表示存在值但未知;我不确定哪种情况会更好。

答案 1 :(得分:2)

如果使用df[!, :C] .= nothing初始化列,则其元素类型为Nothing。将DateTime写入此列时,Julia尝试将它们转换为Nothing,但失败。 我不确定这是否是最有效或推荐的解决方案,但是如果您将该列初始化为DateTimeNothing

的并集
df[!, :C] = Vector{Union{DateTime, Nothing}}(nothing, size(df, 1))

您的示例应该可以使用。