Arrays 按多个键对dict数组进行排序,单位:Julia
我有一个很大的Arrays 按多个键对dict数组进行排序,单位:Julia,arrays,sorting,dictionary,julia,Arrays,Sorting,Dictionary,Julia,我有一个很大的Dicts数组,它们看起来都像这样 { "id": 12345, "user_id": "6789", "question_id": "some_question_id", "correct": "true", "actions": "...", "consequentiality": 0, "timestamp": 1505123456.000 } 我需要按(question\u id,user\u id,id,residentiality)对它们进
Dict
s数组,它们看起来都像这样
{
"id": 12345,
"user_id": "6789",
"question_id": "some_question_id",
"correct": "true",
"actions": "...",
"consequentiality": 0,
"timestamp": 1505123456.000
}
我需要按(question\u id,user\u id,id,residentiality)
对它们进行排序,其中question\u id
移动得最慢,而residentiality
移动得更快——有点像分组和子分组,如果愿意的话,但在某些情况下我需要对有序数组执行交换,其中大多数都是跨群体发生的。我一直在玩Base.sort
,通过和lt
向传递不同的函数。我想到的最好的方法是将多个排序一个接一个地组合起来,并通过
子句将不同的键传递给每个,比如
sort(sort(sort(sort(df, by=x->x["question_id"]), by=x->x["user_id"] ...
你明白了。到目前为止,我还无法获得令人满意的稳定排序,即使使用了稳定的算法,如MergeSort
帮忙
EDIT在by
子句中使用元组有意义吗?但是,如何反转非数值元素的顺序?这里演示了一种在注释中使用lt=…
清理解决方案的方法。注意,这只适用于元组,因为它为元组重新定义了isless
。如果有热情的话,也许像这样的东西可以加入朱莉娅或其他一些软件包中
julia> struct RevNext
end
julia> import Base: isless
julia> function isless(t1::Tuple, t2::Tuple)
n1, n2 = length(t1), length(t2)
reverse = false
for i = 1:min(n1, n2)
a, b = t1[i], t2[i]
if !isequal(a, b)
return reverse ? isless(b, a) : isless(a,b)
else
reverse = isa(a,RevNext)
end
end
return n1 < n2
end
WARNING: Method definition isless(Tuple, Tuple) ...
isless (generic function with 53 methods)
尝试sort(df,by=x->getindex.(x,(“问题id”,“用户id”,“id”,“结果性”))
关于反转非数值的顺序,这可能需要lt=
参数中的自定义小于函数。例如,要反转非数值用户名字段的排序,可以执行:sort(df,lt=(x,y)->lexless((x[“问题id”),false,x[“id”],(y[“ques选项id],x[“用户名”]>y[“用户名”],y[“id”])))
。首先按question\u id
进行排序,然后按username
进行反向排序,然后按id
进行排序(诀窍是将false与username
上的大于表达式进行比较,从而颠倒顺序)确定,并进行最新编辑(交换true和false,并更改比较符号)我可以把一切都安排好。我很困惑,因为“id”
出现了错误,我无法逆转。现在的任务是让它看起来更漂亮,检查效率,或者定义一个函数使它更干净。我想我更喜欢另一个解决方案。两者都有点笨重,但另一个更紧凑,同样通用(不太通用)正如这一个–至少它不涉及改变相邻参数语义的参数。最初,我希望sort
的rev
参数接受布尔元组以反转或不反转传入的元组。
julia> M = [Dict(:a=>rand(),:b=>rand(Bool)) for i=1:10]
10-element Array{Dict{Symbol,Any},1}:
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.735352),Pair{Symbol,Any}(:b, true))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.537437),Pair{Symbol,Any}(:b, true))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.314947),Pair{Symbol,Any}(:b, true))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.9723),Pair{Symbol,Any}(:b, false))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.605042),Pair{Symbol,Any}(:b, true))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.256509),Pair{Symbol,Any}(:b, false))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.133487),Pair{Symbol,Any}(:b, false))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.320249),Pair{Symbol,Any}(:b, false))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.409549),Pair{Symbol,Any}(:b, true))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.421471),Pair{Symbol,Any}(:b, true))
julia> sort(M,by=x->(x[:b], RevNext(), x[:a]))
10-element Array{Dict{Symbol,Any},1}:
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.9723),Pair{Symbol,Any}(:b, false))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.320249),Pair{Symbol,Any}(:b, false))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.256509),Pair{Symbol,Any}(:b, false))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.133487),Pair{Symbol,Any}(:b, false))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.735352),Pair{Symbol,Any}(:b, true))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.605042),Pair{Symbol,Any}(:b, true))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.537437),Pair{Symbol,Any}(:b, true))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.421471),Pair{Symbol,Any}(:b, true))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.409549),Pair{Symbol,Any}(:b, true))
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.314947),Pair{Symbol,Any}(:b, true))