【发布时间】:2020-02-23 21:54:03
【问题描述】:
我需要将“非”运算符应用于 Julia 中的零和一矩阵。 在 Matlab 中我会这样做:
A=not(B);
在 Julia 我尝试这样做:
A = .~ B;
和
A = .! B;
它应该将零变为一,将一变为零,但结果我得到错误,或者所有矩阵元素都是一些我没有输入的负数。 提前致谢!
【问题讨论】:
我需要将“非”运算符应用于 Julia 中的零和一矩阵。 在 Matlab 中我会这样做:
A=not(B);
在 Julia 我尝试这样做:
A = .~ B;
和
A = .! B;
它应该将零变为一,将一变为零,但结果我得到错误,或者所有矩阵元素都是一些我没有输入的负数。 提前致谢!
【问题讨论】:
A = .!B 的问题是逻辑否定 !(::Int64) 没有为整数定义。这是有道理的:应该说,!3 合理地给予什么?
既然您想要执行逻辑运算,那么您是否有更深层次的原因为什么要从整数开始?
您或许可以改用BitArray,它的效率要高得多,并且在大多数操作中应该表现得像普通的Array。
您可以轻松地将整数矩阵转换为BitArray。之后,应用逻辑不按预期工作。
julia> A = rand(0:1, 5,5)
5×5 Array{Int64,2}:
0 0 0 1 1
0 1 0 0 1
0 1 1 1 0
1 1 0 0 0
1 1 1 0 0
julia> B = BitArray(A)
5×5 BitArray{2}:
0 0 0 1 1
0 1 0 0 1
0 1 1 1 0
1 1 0 0 0
1 1 1 0 0
julia> .!B
5×5 BitArray{2}:
1 1 1 0 0
1 0 1 1 0
1 0 0 0 1
0 0 1 1 1
0 0 0 1 1
这里的关键部分是BitArray 的元素类型(eltype) 是Bool,它的否定显然是很好定义的。从这个意义上说,您还可以使用B = Bool.(A) 将所有元素转换为布尔值。
【讨论】:
BitArray 有点模糊了这个问题。如果只有 0 和 1,请使用 Bool.(B) 将所有元素转换为可以进行逻辑运算的逻辑值。在大多数情况下,它确实也返回BitArray,但它也更清楚为什么它可以达到IMO的目的。
对于从A (其中A 是数字矩阵)到具有真值且其他地方有零和假值的布尔矩阵的一般解决方案,您可以这样做:
julia> A = rand(0:3, 5, 5)
5×5 Array{Int64,2}:
1 0 1 0 3
2 0 1 1 0
2 1 1 3 1
1 0 3 0 3
1 3 3 1 2
julia> (!iszero).(A)
5×5 BitArray{2}:
1 0 1 0 1
1 0 1 1 0
1 1 1 1 1
1 0 1 0 1
1 1 1 1 1
分解这里发生的事情:
iszero 是一个谓词,用于测试标量值是否为零!iszero 是一个谓词,如果标量值不为零则返回(!iszero).(A) 在矩阵 A 上广播 !iszero 函数
这将返回一个BitArray,其中包含所需的零(假)和一(真)模式。请注意,在数组上下文中,false 打印为0,true 打印为1(它们在数字上相等)。您也可以像这样与号码0 进行比较:
julia> A .!= 0
5×5 BitArray{2}:
1 0 1 0 1
1 0 1 1 0
1 1 1 1 1
1 0 1 0 1
1 1 1 1 1
【讨论】:
您也可以自己滚动:
not(x) = (x |> Bool |> !) |> Float64
定义了一种方法,它将x 转换为boolean,不应用,然后将结果转换回数字。 not.(A) 将在数组 A 上按元素进行操作。这里|> 将输出重定向到下一个方法并与广播一起使用。
【讨论】:
虽然在概念上不是最干净的,A=1.-B 会做你想做的事。 ~ 的问题在于它不是对整数执行按位运算,这会产生负数。不知道! 有什么问题,除非它可能应该是!.B
【讨论】:
A=1 .- B 是个好主意!我没有想到。它完成了工作。我也尝试过 '!.B` ,但它不起作用。感谢您的智能解决方案!