Julia中有空值的DataFrame列?

3
我将尝试解释Julia中的DataFrames是如何工作的,但我遇到了一些困难。
通常我使用DataFrames进行工作——在Python中——每个模拟步骤都会添加新列,并用值填充每一行。
例如,我有一个包含输入数据的DataFrame:
using DataFrames

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

现在,假设我基于那些AB列进行计算,生成第三列C,其中包含DateTime对象。但是,并非所有行都生成DateTime对象,它们可能为空。

  1. Julia如何处理这种用例?
  2. 我应该如何创建新的C列并在for r in eachrow(df)中分配值?
解释:
1. Julia可以使用if语句检查是否存在DateTime对象,如果存在则执行相应操作,否则跳过。 2. 可以使用df.C = Vector{Union{Nothing, DateTime}}(undef, nrow(df))创建一个未初始化的C列,然后在循环中使用df.C[i] = value为每一行分配值。
# 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个回答

5

这个操作的高效方法是:

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表示值存在但未知;我不确定哪个在您的情况下更好)。

我会尝试这种方法。谢谢,这有助于更好地了解如何在Julia中工作。 - M.E.
这是 https://docs.julialang.org/en/v1/manual/performance-tips/index.html#kernel-functions-1 性能建议的一个特定应用,对于性能关键代码而言,这将是相关的。 - Bogumił Kamiński
谢谢,我会查看链接。 - M.E.
仅补充Kaminski的答案... 在许多Julia操作中,使用nothing会导致运行时错误,而使用missing则会静默地传播missing。如果您选择使用missing,请不要忘记将DataFrame列定义为Union{T,Missing},例如Union{Float64,Missing} - Antonello

4
如果您使用 df[!,:C] .= nothing 来初始化列,则它的元素类型为 Nothing 。当向此列写入 DateTime 时,Julia 会尝试将其转换为 Nothing 并失败。
我不确定这是否是最有效或推荐的解决方案,但如果您将该列初始化为 DateTime Nothing 的联合,则问题可能得到解决。
df[!, :C] = Vector{Union{DateTime, Nothing}}(nothing, size(df, 1))

你的例子应该可以正常运行。


谢谢,我也注意到我可以创建一个类型为Any的数组C = [],然后在for eachrow(df)循环中使用push!函数添加元素。循环结束后,只需将C附加到数据框df.C = C即可。 - M.E.
1
不推荐创建 Any 类型的向量(除非确实需要),因为后续使用它们会很慢(编译器不知道它们所持有的值的类型)。 - Bogumił Kamiński
完美的答案!我会使用nrow(df)而不是size(df, 1),在我的笔记本电脑上快了20纳秒;-) - HHFox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接