DataStructures.jl提供了一组很棒的工具,其中一个是counter。相应的Python对象Counter
提供了most_common
方法。如何在朱莉娅实施?
答案 0 :(得分:3)
可以通过select!
完成繁重的工作。以下内容应该重现Python中most_common
的行为:
using DataStructures
most_common(c::Accumulator) = most_common(c, length(c))
most_common(c::Accumulator, k) = select!(collect(c), 1:k, by=kv->kv[2], rev=true)
直到Julia获得专注于函数参数by=kv->kv[2]
(计划中)的能力,并且直到索引到返回视图(也是计划的),它将会有性能影响,它将执行不必要的复制以创建正确长度的输出向量。但只要它不是性能关键,上面应该可以正常工作。
性能问题当然可以通过更谨慎,低级别的实现来处理。我不知道现有的功能,但它可能是DataStructures.jl或Julia本身的一个有价值的补充。对于不是计数器或累加器的关联集合也是有意义的,但是应该将其命名为其他东西。
答案 1 :(得分:0)
要更新此问题,我正在使用Julia v1.2.1,并且没有select!
afaik。
这是我使用的@Toivo实现的一个小修改:
using DataStructures
most_common(c::Accumulator) = most_common(c, length(c))
most_common(c::Accumulator, k) = sort(collect(c), by=kv->kv[2], rev=true)[1:k]
这将返回一个具有::Array{Pair{String,Int}},1
个成员的k
,类似于Python Counter.most_common(k)
,该Python返回一个由k
组成的元组对的列表。
示例:
使用Python Counter
和Julia DataStructures.counter
在“哈姆雷特”中找到十个最常见的单词。
Python:
>>> import re
>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]
朱莉娅:
> import DataStructures: counter
> open("hamlet.txt") do f
> words = matchall(r"\w+", read(f, String))
> counter(words)|> most_common
> end
10-element Array{Pair{Any,Int64},1}:
"the" => 1143
"and" => 966
"to" => 762
...
我没有足够的经验来评论效率,但是很想听听专家的意见。