Arrays 删除Julia中的连续重复项
我对Julia很陌生,我不知道如何删除数组中的连续重复项。例如,如果使用此数组:Arrays 删除Julia中的连续重复项,arrays,duplicates,julia,Arrays,Duplicates,Julia,我对Julia很陌生,我不知道如何删除数组中的连续重复项。例如,如果使用此数组: `v=[8,8,8,9,5,5,8,8,1];` 我希望获得向量v1,以便: v1=[8,9,5,8,1] 有人能帮我吗?非常感谢。一种方法是定义: function fastuniq(v) v1 = Vector{eltype(v)}() if length(v)>0 laste = v[1] push!(v1,laste) for e in v if e
`v=[8,8,8,9,5,5,8,8,1];`
我希望获得向量v1,以便:
v1=[8,9,5,8,1]代码>
有人能帮我吗?非常感谢。一种方法是定义:
function fastuniq(v)
v1 = Vector{eltype(v)}()
if length(v)>0
laste = v[1]
push!(v1,laste)
for e in v
if e != laste
laste = e
push!(v1,laste)
end
end
end
return v1
end
通过此功能,您可以:
julia> println(fastuniq(v))
[8,9,5,8,1]
但是,在处理数组时,需要确定元素是深度复制还是浅复制。对于整数,这无关紧要。这比@DanGetz的函数慢得多,但这里有一种方法可以在一行中实现:
function notsofastunique(v)
return [v[1]; v[2:end][v[2:end] .!= v[1:end-1]]]
end
>println(notsofastunique(v))
[8,9,5,8,1]
也许它对寻找矢量化解决方案的人很有用。在spirit@niczky12一行解决方案目标中,以下使用了迭代器.jl
包(非常有用,并且缓慢地迁移到Base中)
没有做过任何基准测试,但是应该可以(但是比基于
的函数的较长的要慢) 中有一个rle
函数(运行长度编码)正是这样做的。只是为了练习
这里有另一个小函数可以用来做这件事,这个函数只适用于非负值(包括0)
编辑:
根据注释中的输入,再添加一个版本。我认为这个版本应该更快,也许你可以测试一下:)这个版本也应该适用于负数
function anotherone(v)
v1 = falses(length(v))
v1[1]=true
for e = 2:length(v)
if v[e] != v[e-1]
v1[e] = true
end
end
return v[v1]
end
是的,你是对的,它应该包括1。对不起@SamyJelassi您可以编辑您的问题以包含1
。这是最致命的方法吗?非常快。也许一些优化指令,如
的上的@inbounds
会有所帮助。推代码>功能经过优化,使许多小推送代码>es不经常执行内存分配。如果删除的元素百分比通常很小,您可能还需要一个sizehint!优化输出阵列的分配。另一个加速它的方法(如果经常是没有找到副本的情况)是使用一个功能快速扫描第一个副本,如果没有找到副本,只需返回原始数组,或者使用copy
(取决于是否需要副本)很好的解决方案。它还发现了rle
中的一个潜在缺陷:一个空向量产生一个异常(在访问第一个元素之前没有检查)。本质上,当v
是一个空向量时,不变量inverse_rle(rle(v)…)==v
应该仍然有效。更简单的方法是直接使用逻辑索引。将v1
设置为逻辑数组(v1=false(长度(v))
),然后在为其分配元素的位置将其设置为true。现在您可以简单地返回v[v1]
,它将适用于所有值和元素类型!(填入(NaN,n),a[1:(n端)];v[v.!=滞后(v)]`
function anotherone(v)
v1 = zeros(eltype(v),length(v))
v1[1]=v[1]+1
for e = 2:length(v)
if v[e] != v[e-1]
v1[e] = v[e]+1
end
end
return v1[find(v1)]-1
end
function anotherone(v)
v1 = falses(length(v))
v1[1]=true
for e = 2:length(v)
if v[e] != v[e-1]
v1[e] = true
end
end
return v[v1]
end