在 Julia 中压平字典
Flatten a Dictionary in Julia
我有 Julia 的字典
In[27]: CollectedOutputCount
Out[27]: Dict{Any,Any} with 3 entries:
2 => Any[278963,1,1]
3 => Any[283339,1,1]
1 => Any[272878,0,0,0]
我想从包含每个 Dict 条目总和的 Dict 内容创建一个数组 2:end。每个 Dict 条目中的第一个值是一个标签。输出需要类似于
Output = [ label sum;label sum;...]
在这种情况下,它将是
Output = [278963 2;283339 2;272878 0]
除了循环迭代之外,还有什么方法可以做到这一点吗?是否有一些函数可以将 Dict 展平为数组(可能在尺寸不均匀的地方使用填充)?
我不确定可以以这种自定义方式展平字典的函数,但是您可以使用 map
:
来避免循环
根据你的字典:
CollectedOutputCount = Dict(2 => [278963,1,1], 3 => [283339,1,1], 1 => [272878,0,0,0], 4 => [1234])
你可以把它压平成[label sum;标签总和...] 在一行中:
vcat(map(a -> [a[1] sum(a[2:end])], values(CollectedOutputCount))...)
这给你:
4x2 Array{Int64,2}:
1234 0
278963 2
283339 2
272878 0
map
将函数应用于数组的所有元素,在本例中为字典的值迭代器。然后您可以使用 vcat
附加这些。请注意当字典中没有值时 sum
是如何给你 0 的,只有 1 元素作为标签 (1234 0)
.
@niczky12 中的替代等效选项,但使用列表理解;
>>> mydict = Dict(2 => [278963,1,1], 3 => [283339,1,1],
1 => [272878,0,0,0], 4 => [1234]);
>>> comp = [[a[1] sum(a[2:end])] for a in values(mydict)];
主要区别是使用列表理解而不是 map
函数。它们是等价的(在本例中)。
然而,这里的 comp
是一个包含 4 个条目的数组,其中每个条目都是一个 1x2 数组。将其翻译成 4x2 array
:
>>> vcat(comp...)
4x2 Array{Int64,2}:
1234 0
278963 2
283339 2
272878 0
但是,如果字典的所有数组都具有相同的长度,您可以将它们连接起来,并替换最后一列:
>>> mydict = Dict(2 => [278963,1,0], 3 => [283339,1,1], 1 => [272878,0,0])
>>> vals = hcat(values(mydict)...)';
>>> hcat(vals[:, 1], sum(vals[:, 2:end], 2))
3x2 Array{Int64,2}:
278963 1
283339 2
272878 0
不过,迭代版本可能更有效。
最后,一个完全迭代的版本,它不会创建不必要的临时存储:
r = zeros(Int64, length(mydict), 2)
for (n, b) in enumerate(values(mydict))
r[n, 1] = b[1]
r[n, 2] = sum(b[2:end])
end
我有 Julia 的字典
In[27]: CollectedOutputCount
Out[27]: Dict{Any,Any} with 3 entries:
2 => Any[278963,1,1]
3 => Any[283339,1,1]
1 => Any[272878,0,0,0]
我想从包含每个 Dict 条目总和的 Dict 内容创建一个数组 2:end。每个 Dict 条目中的第一个值是一个标签。输出需要类似于
Output = [ label sum;label sum;...]
在这种情况下,它将是
Output = [278963 2;283339 2;272878 0]
除了循环迭代之外,还有什么方法可以做到这一点吗?是否有一些函数可以将 Dict 展平为数组(可能在尺寸不均匀的地方使用填充)?
我不确定可以以这种自定义方式展平字典的函数,但是您可以使用 map
:
根据你的字典:
CollectedOutputCount = Dict(2 => [278963,1,1], 3 => [283339,1,1], 1 => [272878,0,0,0], 4 => [1234])
你可以把它压平成[label sum;标签总和...] 在一行中:
vcat(map(a -> [a[1] sum(a[2:end])], values(CollectedOutputCount))...)
这给你:
4x2 Array{Int64,2}:
1234 0
278963 2
283339 2
272878 0
map
将函数应用于数组的所有元素,在本例中为字典的值迭代器。然后您可以使用 vcat
附加这些。请注意当字典中没有值时 sum
是如何给你 0 的,只有 1 元素作为标签 (1234 0)
.
@niczky12 中的替代等效选项,但使用列表理解;
>>> mydict = Dict(2 => [278963,1,1], 3 => [283339,1,1],
1 => [272878,0,0,0], 4 => [1234]);
>>> comp = [[a[1] sum(a[2:end])] for a in values(mydict)];
主要区别是使用列表理解而不是 map
函数。它们是等价的(在本例中)。
然而,这里的 comp
是一个包含 4 个条目的数组,其中每个条目都是一个 1x2 数组。将其翻译成 4x2 array
:
>>> vcat(comp...)
4x2 Array{Int64,2}:
1234 0
278963 2
283339 2
272878 0
但是,如果字典的所有数组都具有相同的长度,您可以将它们连接起来,并替换最后一列:
>>> mydict = Dict(2 => [278963,1,0], 3 => [283339,1,1], 1 => [272878,0,0])
>>> vals = hcat(values(mydict)...)';
>>> hcat(vals[:, 1], sum(vals[:, 2:end], 2))
3x2 Array{Int64,2}:
278963 1
283339 2
272878 0
不过,迭代版本可能更有效。
最后,一个完全迭代的版本,它不会创建不必要的临时存储:
r = zeros(Int64, length(mydict), 2)
for (n, b) in enumerate(values(mydict))
r[n, 1] = b[1]
r[n, 2] = sum(b[2:end])
end