Octave 如何在Julia中的数组中执行条件赋值?

Octave 如何在Julia中的数组中执行条件赋值?,octave,julia,Octave,Julia,在八度音阶中,我能做到 octave:1> A = [1 2; 3 4] A = 1 2 3 4 octave:2> A(A>1) -= 1 A = 1 1 2 3 但在Julia中,等效语法不起作用 julia> A = [1 2; 3 4] 2x2 Array{Int64,2}: 1 2 3 4 julia> A[A>1] -= 1 ERROR: `isless` has no method mat

在八度音阶中,我能做到

octave:1> A = [1 2; 3 4]
A =

   1   2
   3   4

octave:2> A(A>1) -= 1
A =

   1   1
   2   3
但在Julia中,等效语法不起作用

julia> A = [1 2; 3 4]
2x2 Array{Int64,2}:
 1  2
 3  4

julia> A[A>1] -= 1
ERROR: `isless` has no method matching isless(::Int64, ::Array{Int64,2})
 in > at operators.jl:33

如何在Julia中有条件地为某些数组或矩阵元素赋值?

您的问题不在于赋值本身,而在于
A>1本身不起作用。您可以使用elementwise
A.>1

julia> A = [1 2; 3 4];

julia> A .> 1
2×2 BitArray{2}:
 false  true
  true  true

julia> A[A .> 1] .-= 1000;

julia> A
2×2 Array{Int64,2}:
    1  -998
 -997  -996
更新:


注意,在现代Julia(>=0.7)中,我们需要使用
来表示我们想要广播动作(这里,减去标量1000),以匹配左侧过滤目标的大小。(最初提出这个问题时,我们需要
A.>1
中的点,但不需要
-=
中的点)

要使它在Julia 1.0中工作,需要将
=
更改为
=
。换言之:

julia> a = [1 2 3 4]

julia> a[a .> 1] .= 1

julia> a
1×4 Array{Int64,2}:
 1  1  1  1
否则你会得到类似的结果

错误:MethodError:没有与setindex\u shape\u检查匹配的方法(::Int64,::Int64)


在Julia v1.0中,您可以使用
replace功能,而不是逻辑索引,具有相当大的加速比:

julia> B = rand(0:20, 8, 2);

julia> @btime (A[A .> 10] .= 10) setup=(A=copy($B))
  595.784 ns (11 allocations: 4.61 KiB)

julia> @btime replace!(x -> x>10 ? 10 : x, A) setup=(A=copy($B))
  13.530 ns ns (0 allocations: 0 bytes)
对于较大的矩阵,差异大约是加速比的10倍

加速的原因是逻辑索引解决方案依赖于创建一个中间数组,而
replace避免了这种情况

这是一种略为简洁的写作方式

replace!(x -> min(x, 10), A)
不过,使用
min
似乎没有任何加速效果

这是另一个几乎同样快的解决方案:

A .= min.(A, 10)
这也避免了分配