从julia中的[1,2,0,0,4,0]中查找非零元素的索引,并使用它们创建一个Arrray
我知道有一个函数可以做到这一点,例如:从julia中的[1,2,0,0,4,0]中查找非零元素的索引,并使用它们创建一个Arrray,julia,Julia,我知道有一个函数可以做到这一点,例如: A = [1,2,0,0,4,0] find(A) 3-element Array{Int64,1}: 1 2 5 我试着用我自己的方式去做,但是,我被困在这里了 for i=1:endof(A) if A[i] != 0 [] end end 提前谢谢。我注意到这个问题真的很混乱(因为表述不当,很抱歉)。所以,有两个可能的答案:一个是[1,2,4],它是一个包含非零元素的数组;另一个是[1,2,5],它是非零元素索引
A = [1,2,0,0,4,0]
find(A)
3-element Array{Int64,1}:
1
2
5
我试着用我自己的方式去做,但是,我被困在这里了
for i=1:endof(A)
if A[i] != 0
[]
end
end
提前谢谢。我注意到这个问题真的很混乱(因为表述不当,很抱歉)。所以,有两个可能的答案:一个是
[1,2,4]
,它是一个包含非零元素的数组;另一个是[1,2,5]
,它是非零元素索引的数组
让我们从第一个选项开始
A = [1,2,0,0,4,0]
B = []
for i=1:endof(A)
if A[i] != 0
push!(B,i)
end
end
println(B)
输出为Any[1,2,5]
但是,类型不是我想要的。使用typeof(B)
显示Array{Any,1}
,因此我添加了以下代码:
B = Array{Int64}(B)
println(B)
typeof(B)
结果是理想的
[1,2,5]
Array{Int64,1}
为了提高其效率,根据注释中的建议,我在循环之前使用eltype()
函数指定了B的类型,如下所示:
A1 = [1,2,0,0,4,0] #The default type is Array{Int64,1}
B1 = eltype(A1)[] #Define the type of the 0 element array B with the type of A
#B1 = eltype(typeof(A))[] this is also valid
for i=1:endof(A1)
if A1[i] != 0
push!(B1::Array{Int64,1},i::Int64)
end
end
println(B1)
typeof(B1)
然后,输出再次是所需的
[1,2,5]
Array{Int64,1}
最简单的方法是使用函数find()
。然而,由于我是一个初学者,我想用另一种方式来做。然而,@DNF提供的另一个替代方案在他测试过的案例中表现优于find()
(参见下面的答案)
其他用户(@Harrison Grodin和@pi)在本次讨论中提供了第二个选项,它创建了一个包含非零元素的输出矩阵
谢谢大家的帮助 这里有几个选项 使用您开始使用的策略,您可以使用
push代码>在for
循环中
julia> B = Int[]
0-element Array{Int64,1}
julia> for element = A
if element != 0
push!(B, element)
end
end
julia> B
3-element Array{Int64,1}:
1
2
4
您也可以选择使用短路评估
julia> for element = A
element != 0 && push!(B, element)
end
julia> for element = A
element == 0 || push!(B, element)
end
filter
和列表理解也是有效的
julia> B = [element for element = A if element != 0]
3-element Array{Int64,1}:
1
2
4
julia> filter(n -> n != 0, A)
3-element Array{Int64,1}:
1
2
4
编辑:由于OP的评论,我意识到期望的结果是非零元素的索引,而不是元素本身。这可以通过以下简单方法实现:
这里有一个选择:
function myfind(c)
a = similar(c, Int)
count = 1
@inbounds for i in eachindex(c)
a[count] = i
count += (c[i] != zero(eltype(c)))
end
return resize!(a, count-1)
end
在我测试的所有案例中,它实际上都优于find
,尽管对于您发布的非常小的示例向量,差异可以忽略不计。避免分支和动态增长索引数组可能有一些性能优势。您能解释一下问题所在吗?您正在寻找推送代码>?您还可以使用@less find(a)
查看find
的源代码。我希望社区不要急于否决新成员@用户7546279,选择一个昵称,我们会更爱你。看看B=A[A.!=0]
也能用(谢谢@Ismael VC)实际上B=A[A.!=0]
不是我想要的。这样做是为了排除零元素。我想做的是用非零元素的索引创建一个数组,而不是用非零元素。我下面的回答也不正确。所需输出应为[1,2,5]
,对应于1
2
和4
的位置。很抱歉,我注意到这个问题太复杂了。要从一开始就获得正确的类型,您可以使用B=eltype(A)[]
。最后看一看。特别是,在全局范围内执行操作的速度很慢。再次感谢您,这些操作对我帮助很大。请注意,您不需要重新分配推送的结果!(B…)
返回B
。那个表示修改了第一个参数。问题是我注意到问题不太清楚。我想要的是一个包含非零元素索引的数组,而不是一个非零元素数组。不过,非常感谢你!这太有用了。@Pau啊,我明白了!我已经更新了我的回复,加入了寻找指数的解决方案。希望有帮助!:)您可以在数组a
上调用countnz
,以获取数组中非零的n
,然后用正确的维度预先分配a
。当然,但是您必须在数组上花费额外的时间,这似乎是白费力气。基本上,这将是工作的两倍。我想这取决于您希望优化的性能的特定方面。我的建议反映了我对最小化内存事务的偏好countnz
不分配内存,使用它预分配a
只使用必要的内存。
function myfind(c)
a = similar(c, Int)
count = 1
@inbounds for i in eachindex(c)
a[count] = i
count += (c[i] != zero(eltype(c)))
end
return resize!(a, count-1)
end