如何在 Julia 中将 IndexedTable 转换为 DataFrame?

Ant*_*llo 5 type-conversion dataframe julia

在快速解释性工作中,IndexedTables似乎比DataFrames处理单个元素(例如选择或“更新”)要快得多,但DataFrames具有更好的功能生态系统,例如绘图、导出......

因此,在工作流的某个时刻,我想将 IndexedTable 转换为 DataFrame,例如

using DataFrames, IndexedTables, IndexedTables.Table

tn = Table(
    Columns(
        param  = String["price","price","price","price","waterContent","waterContent"],
        item   = String["banana","banana","apple","apple","banana", "apple"],
        region = Union{String,DataArrays.NAtype}["FR","UK","FR","UK",NA,NA]
    ),
    Columns(
       value2000 = Float64[2.8,2.7,1.1,0.8,0.2,0.7],
       value2010 = Float64[3.2,2.9,1.2,0.8,0.2,0.8],
    )
)
Run Code Online (Sandbox Code Playgroud)

到 >>

df_tn = DataFrame(
    param     = String["price","price","price","price","waterContent","waterContent"],
    item      = String["banana","banana","apple","apple","banana", "apple"],
    region    = Union{String,DataArrays.NAtype}["FR","UK","FR","UK",NA,NA],
    value2000 = Float64[2.8,2.7,1.1,0.8,0.2,0.7],
    value2010 = Float64[3.2,2.9,1.2,0.8,0.2,0.8],
)
Run Code Online (Sandbox Code Playgroud)

或者

t = Table(
    Columns(
        String["price","price","price","price","waterContent","waterContent"],
        String["banana","banana","apple","apple","banana", "apple"],
        Union{String,DataArrays.NAtype}["FR","UK","FR","UK",NA,NA]
    ),
    Columns(
       Float64[2.8,2.7,1.1,0.8,0.2,0.7],
       Float64[3.2,2.9,1.2,0.8,0.2,0.8],
    )
)
Run Code Online (Sandbox Code Playgroud)

到 >>

df_t = DataFrame(
    x1 = String["price","price","price","price","waterContent","waterContent"],
    x2 = String["banana","banana","apple","apple","banana", "apple"],
    x3 = Union{String,DataArrays.NAtype}["FR","UK","FR","UK",NA,NA],
    x4 = Float64[2.8,2.7,1.1,0.8,0.2,0.7],
    x5 = Float64[3.2,2.9,1.2,0.8,0.2,0.8]
)
Run Code Online (Sandbox Code Playgroud)

我可以找到与表交互的单个“行”值pair()

for (i,pair) in enumerate(pairs(tn))
    rowValues = []
    for (j,section) in enumerate(pair)
        for item in section
            push!(rowValues,item)
        end
    end
    println(rowValues)
end
Run Code Online (Sandbox Code Playgroud)

但是,我无法获取列名称和类型,我想按列工作会更有效。

编辑:我确实设法使用上面的代码获取了“列”类型,我现在只需要获取列名(如果有):

colTypes = Union{Union,DataType}[]

for item in tn.index.columns
  push!(colTypes, eltype(item))
end
for item in tn.data.columns
  push!(colTypes, eltype(item))
end
Run Code Online (Sandbox Code Playgroud)

EDIT2:根据要求,这是一个 IndexedTable 的例子,它会使用(当前)Dan Getz 答案转换列名失败,因为“索引”列被命名为元组,但“数据”列是正常的元组:

t_named_idx = Table(
    Columns(
        param  = String["price","price","price","price","waterContent","waterContent"],
        item   = String["banana","banana","apple","apple","banana", "apple"],
        region = Union{String,DataArrays.NAtype}["FR","UK","FR","UK",NA,NA]
    ),
    Columns(
       Float64[2.8,2.7,1.1,0.8,0.2,0.7],
    )
)
Run Code Online (Sandbox Code Playgroud)

问题似乎出在 IndexedTable API 中,特别是在columns(t)函数中,它不区分索引和值。

Dan*_*etz 3

以下转换函数:

\n\n
toDataFrame(cols::Tuple, prefix="x") = \n  DataFrame(;(Symbol("$prefix$c") => cols[c] for c in fieldnames(cols))...)\n\ntoDataFrame(cols::NamedTuples.NamedTuple, prefix="x") = \n  DataFrame(;(c => cols[c] for c in fieldnames(cols))...)\n\ntoDataFrame(t::IndexedTable) = toDataFrame(columns(t))\n
Run Code Online (Sandbox Code Playgroud)\n\n

给出(在 Julia 0.6 上,并按tn问题t中的定义):

\n\n
julia> tn\nparam           item      region \xe2\x94\x82 value2000  value2010\n\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n"price"         "apple"   "FR"   \xe2\x94\x82 1.1        1.2\n"price"         "apple"   "UK"   \xe2\x94\x82 0.8        0.8\n"price"         "banana"  "FR"   \xe2\x94\x82 2.8        3.2\n"price"         "banana"  "UK"   \xe2\x94\x82 2.7        2.9\n"waterContent"  "apple"   NA     \xe2\x94\x82 0.7        0.8\n"waterContent"  "banana"  NA     \xe2\x94\x82 0.2        0.2\n\njulia> df_tn = toDataFrame(tn)\n6\xc3\x975 DataFrames.DataFrame\n\xe2\x94\x82 Row \xe2\x94\x82 param          \xe2\x94\x82 item     \xe2\x94\x82 region \xe2\x94\x82 value2000 \xe2\x94\x82 value2010 \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 1   \xe2\x94\x82 "price"        \xe2\x94\x82 "apple"  \xe2\x94\x82 "FR"   \xe2\x94\x82 1.1       \xe2\x94\x82 1.2       \xe2\x94\x82\n\xe2\x94\x82 2   \xe2\x94\x82 "price"        \xe2\x94\x82 "apple"  \xe2\x94\x82 "UK"   \xe2\x94\x82 0.8       \xe2\x94\x82 0.8       \xe2\x94\x82\n\xe2\x94\x82 3   \xe2\x94\x82 "price"        \xe2\x94\x82 "banana" \xe2\x94\x82 "FR"   \xe2\x94\x82 2.8       \xe2\x94\x82 3.2       \xe2\x94\x82\n\xe2\x94\x82 4   \xe2\x94\x82 "price"        \xe2\x94\x82 "banana" \xe2\x94\x82 "UK"   \xe2\x94\x82 2.7       \xe2\x94\x82 2.9       \xe2\x94\x82\n\xe2\x94\x82 5   \xe2\x94\x82 "waterContent" \xe2\x94\x82 "apple"  \xe2\x94\x82 NA     \xe2\x94\x82 0.7       \xe2\x94\x82 0.8       \xe2\x94\x82\n\xe2\x94\x82 6   \xe2\x94\x82 "waterContent" \xe2\x94\x82 "banana" \xe2\x94\x82 NA     \xe2\x94\x82 0.2       \xe2\x94\x82 0.2       \xe2\x94\x82\n
Run Code Online (Sandbox Code Playgroud)\n\n

类型信息大部分被保留:

\n\n
julia> typeof(df_tn[:,1])\nDataArrays.DataArray{String,1}\n\njulia> typeof(df_tn[:,4])\nDataArrays.DataArray{Float64,1}\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于未命名的列:

\n\n
julia> t\n\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n"price"         "apple"   "FR" \xe2\x94\x82 1.1  1.2\n"price"         "apple"   "UK" \xe2\x94\x82 0.8  0.8\n"price"         "banana"  "FR" \xe2\x94\x82 2.8  3.2\n"price"         "banana"  "UK" \xe2\x94\x82 2.7  2.9\n"waterContent"  "apple"   NA   \xe2\x94\x82 0.7  0.8\n"waterContent"  "banana"  NA   \xe2\x94\x82 0.2  0.2\n\njulia> df_t = toDataFrame(t)\n6\xc3\x975 DataFrames.DataFrame\n\xe2\x94\x82 Row \xe2\x94\x82 x1             \xe2\x94\x82 x2       \xe2\x94\x82 x3   \xe2\x94\x82 x4  \xe2\x94\x82 x5  \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 1   \xe2\x94\x82 "price"        \xe2\x94\x82 "apple"  \xe2\x94\x82 "FR" \xe2\x94\x82 1.1 \xe2\x94\x82 1.2 \xe2\x94\x82\n\xe2\x94\x82 2   \xe2\x94\x82 "price"        \xe2\x94\x82 "apple"  \xe2\x94\x82 "UK" \xe2\x94\x82 0.8 \xe2\x94\x82 0.8 \xe2\x94\x82\n\xe2\x94\x82 3   \xe2\x94\x82 "price"        \xe2\x94\x82 "banana" \xe2\x94\x82 "FR" \xe2\x94\x82 2.8 \xe2\x94\x82 3.2 \xe2\x94\x82\n\xe2\x94\x82 4   \xe2\x94\x82 "price"        \xe2\x94\x82 "banana" \xe2\x94\x82 "UK" \xe2\x94\x82 2.7 \xe2\x94\x82 2.9 \xe2\x94\x82\n\xe2\x94\x82 5   \xe2\x94\x82 "waterContent" \xe2\x94\x82 "apple"  \xe2\x94\x82 NA   \xe2\x94\x82 0.7 \xe2\x94\x82 0.8 \xe2\x94\x82\n\xe2\x94\x82 6   \xe2\x94\x82 "waterContent" \xe2\x94\x82 "banana" \xe2\x94\x82 NA   \xe2\x94\x82 0.2 \xe2\x94\x82 0.2 \xe2\x94\x82\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑:正如 @Antonello 所指出的,混合命名和未命名元组的情况未正确处理。为了正确处理它,我们可以定义:

\n\n
toDataFrame(t::IndexedTable) = \n  hcat(toDataFrame(columns(keys(t)),"y"),toDataFrame(columns(values(t))))\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后,混合大小写给出的结果如下:

\n\n
julia> toDataFrame(tn2)\n6\xc3\x975 DataFrames.DataFrame\n\xe2\x94\x82 Row \xe2\x94\x82 param          \xe2\x94\x82 item     \xe2\x94\x82 region \xe2\x94\x82 x1  \xe2\x94\x82 x2  \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 1   \xe2\x94\x82 "price"        \xe2\x94\x82 "apple"  \xe2\x94\x82 "FR"   \xe2\x94\x82 1.1 \xe2\x94\x82 1.2 \xe2\x94\x82\n\xe2\x94\x82 2   \xe2\x94\x82 "price"        \xe2\x94\x82 "apple"  \xe2\x94\x82 "UK"   \xe2\x94\x82 0.8 \xe2\x94\x82 0.8 \xe2\x94\x82\n\xe2\x94\x82 3   \xe2\x94\x82 "price"        \xe2\x94\x82 "banana" \xe2\x94\x82 "FR"   \xe2\x94\x82 2.8 \xe2\x94\x82 3.2 \xe2\x94\x82\n\xe2\x94\x82 4   \xe2\x94\x82 "price"        \xe2\x94\x82 "banana" \xe2\x94\x82 "UK"   \xe2\x94\x82 2.7 \xe2\x94\x82 2.9 \xe2\x94\x82\n\xe2\x94\x82 5   \xe2\x94\x82 "waterContent" \xe2\x94\x82 "apple"  \xe2\x94\x82 NA     \xe2\x94\x82 0.7 \xe2\x94\x82 0.8 \xe2\x94\x82\n\xe2\x94\x82 6   \xe2\x94\x82 "waterContent" \xe2\x94\x82 "banana" \xe2\x94\x82 NA     \xe2\x94\x82 0.2 \xe2\x94\x82 0.2 \xe2\x94\x82\n
Run Code Online (Sandbox Code Playgroud)\n