Julia 如何将字典列表转换为数据帧?
我有一个字典列表,其格式与下面类似。名单 是由我不想更改的其他函数生成的。因此, 列表及其目录的存在可以被视为一个给定值Julia 如何将字典列表转换为数据帧?,julia,Julia,我有一个字典列表,其格式与下面类似。名单 是由我不想更改的其他函数生成的。因此, 列表及其目录的存在可以被视为一个给定值 dictlist=[] for i in 1:20 push!(dictlist, Dict(:a=>i, :b=>2*i)) end 是否有一种语法清晰的方法将此列表转换为数据帧?此函数提供了一种可能的解决方案: using DataFrames function DictionariesToDataFrame(dictlist) ret = Dic
dictlist=[]
for i in 1:20
push!(dictlist, Dict(:a=>i, :b=>2*i))
end
是否有一种语法清晰的方法将此列表转换为数据帧?此函数提供了一种可能的解决方案:
using DataFrames
function DictionariesToDataFrame(dictlist)
ret = Dict() #Holds dataframe's columns while we build it
#Get all unique keys from dictlist and make them entries in ret
for x in unique([y for x in [collect(keys(x)) for x in dictlist] for y in x])
ret[x] = []
end
for row in dictlist #Loop through each row
for (key,value) in ret #Use ret to check all possible keys in row
if haskey(row,key) #Is key present in row?
push!(value, row[key]) #Yes
else #Nope
push!(value, nothing) #So add nothing. Keeps columns same length.
end
end
end
#Fix the data types of the columns
for (k,v) in ret #Consider each column
row_type = unique([typeof(x) for x in v]) #Get datatypes of each row
if length(row_type)==1 #All rows had same datatype
row_type = row_type[1] #Fetch datatype
ret[k] = convert(Array{row_type,1}, v) #Convert column to that type
end
end
#DataFrame is ready to go!
return DataFrames.DataFrame(ret)
end
#Generate some data
dictlist=[]
for i in 1:20
push!(dictlist, Dict("a"=>i, "b"=>2*i))
if i>10
dictlist[end-1]["c"]=3*i
end
end
DictionariesToDataFrame(dictlist)
没有好的直接方法(我知道),但是使用像这样的
数据帧
,您可以首先将其转换为命名偶的列表
:
julia> using DataFrames
julia> dictlist=[]
0-element Array{Any,1}
julia> for i in 1:20
push!(dictlist, Dict(:a=>i, :b=>2*i))
end
julia> DataFrame([NamedTuple{Tuple(keys(d))}(values(d)) for d in dictlist])
20×2 DataFrame
│ Row │ a │ b │
│ │ Int64 │ Int64 │
├─────┼───────┼───────┤
│ 1 │ 1 │ 2 │
│ 2 │ 2 │ 4 │
│ 3 │ 3 │ 6 │
│ 4 │ 4 │ 8 │
│ 5 │ 5 │ 10 │
│ 6 │ 6 │ 12 │
│ 7 │ 7 │ 14 │
│ 8 │ 8 │ 16 │
│ 9 │ 9 │ 18 │
│ 10 │ 10 │ 20 │
│ 11 │ 11 │ 22 │
│ 12 │ 12 │ 24 │
│ 13 │ 13 │ 26 │
│ 14 │ 14 │ 28 │
│ 15 │ 15 │ 30 │
│ 16 │ 16 │ 32 │
│ 17 │ 17 │ 34 │
│ 18 │ 18 │ 36 │
│ 19 │ 19 │ 38 │
│ 20 │ 20 │ 40 │
请注意,就在今天,我将此作为一个应用程序打开,因此可能很快就会有更好的支持。您可以
推送代码>中的行(由字典表示)
根据
正如文档所说,这比逐列构造要慢得多,但并不比自己从dicts构造列慢
df = DataFrame()
for row in dictlist
push!(df, row)
end
有一个
使Vector{Dict}
a Tables.jl行表格类型。
如果这样做了(这似乎可能在一个月左右的时间内发生)
那你就可以这么做了
df = DataFrame(dictlist)
对于可能稀疏的帧,这里有一个不会丢失数据,但会添加丢失的数据:
using DataFrames
dictlist = [Dict("a" => 2), Dict("a" => 5, "b" => 8)]
keycol = unique(mapreduce(x -> collect(keys(x)), vcat, dictlist))
df = DataFrame()
df[!, Symbol("Keys")] = keycol
for (i, d) in enumerate(dictlist)
df[!, Symbol(string(i))] = [get(d, k, missing) for k in keycol]
end
println(df)
仅作为参考,它的外观没有任何方法可用于将dict列表转换为数据帧。相反,我们将dict列表转换为dict of list。我的意思是从[(:a=>1,:b=>2),(:a=>3,:b=>4)]
到(:a=>[1,3],:b=>[2,4])
,所以我们需要创建这样的函数:
function to_dict_of_array(data::Array, fields::Array)
# Pre allocate the array needed for speed up in case of large dataset
doa = Dict(Symbol(field) => Array{Any}(undef, length(data)) for field in fields)
for (i, datum) in enumerate(data)
for fn in fields
sym_fn = Symbol(fn)
doa[sym_fn][i] = datum[fn]
end
end
return doa
end
然后我们可以使用该方法创建数据帧
array_of_dict = [Dict("a" => 1, "b" =>2), Dict("a" => 3, "b" =>4)]
required_field = ["a", "b"]
df = DataFrame(to_dict_of_array(array_of_dict, required_field));
这只是一个概念性的例子。应根据用例进行修改。键是否始终相同?如果是这样的话,请澄清问题,以便正确开始。如果不是的话,可能会让你的考试更复杂一些,这样就表明他们可以有一些选择