在 Julia 中将 Dict 转换为 DataFrame

Ale*_* A. 5 macros dictionary type-conversion dataframe julia

假设我有Dict如下定义:

x = Dict{AbstractString,Array{Integer,1}}("A" => [1,2,3], "B" => [4,5,6])
Run Code Online (Sandbox Code Playgroud)

我想将其转换为DataFrame对象(来自DataFrames模块)。构造 aDataFrame的语法与构造字典类似。例如,上面的字典可以手动构建为一个数据框,如下所示:

DataFrame(A = [1,2,3], B = [4,5,6])
Run Code Online (Sandbox Code Playgroud)

我还没有找到从字典到数据框的直接方法,但我认为可以利用句法相似性并编写一个宏来做到这一点。以下根本不起作用,但它说明了我想到的方法:

macro dict_to_df(x)
    typeof(eval(x)) <: Dict || throw(ArgumentError("Expected Dict"))
    return quote
        DataFrame(
            for k in keys(eval(x))
                @eval ($k) = $(eval(x)[$k])
            end
        )
    end
end
Run Code Online (Sandbox Code Playgroud)

我还尝试将其编写为一个函数,当所有字典值具有相同的长度时,它确实有效:

function dict_to_df(x::Dict)
    s = "DataFrame("
    for k in keys(x)
        v = x[k]
        if typeof(v) <: AbstractString
            v = string('"', v, '"')
        end
        s *= "$(k) = $(v),"
    end
    s = chop(s) * ")"
    return eval(parse(s))
end
Run Code Online (Sandbox Code Playgroud)

有没有更好、更快或更惯用的方法来解决这个问题?

Dan*_*etz 5

另一种方法可能是

DataFrame(Any[values(x)...],Symbol[map(symbol,keys(x))...])
Run Code Online (Sandbox Code Playgroud)

获取类型以访问正确的构造函数有点棘手。要获取DataFrames的构造函数列表,我使用了methods(DataFrame).

DataFrame(a=[1,2,3])创建 DataFrame的方式使用关键字参数。要将 splatting ( ...) 用于关键字参数,键必须是符号。在示例中x有字符串,但这些可以转换为符号。在代码中,这是:

DataFrame(;[Symbol(k)=>v for (k,v) in x]...)
Run Code Online (Sandbox Code Playgroud)

最后,如果x最初使用符号,事情会更干净。然后代码会去:

x = Dict{Symbol,Array{Integer,1}}(:A => [1,2,3], :B => [4,5,6])
df = DataFrame(;x...)
Run Code Online (Sandbox Code Playgroud)