我正在寻找一种基于阈值仅使用一个表达式来对numpy N-d数组进行二值化的方法。所以我有这样的事情:
np.random.seed(0)
np.set_printoptions(precision=3)
a = np.random.rand(4, 4)
threshold, upper, lower = 0.5, 1, 0
a现在是:
array([[ 0.02 , 0.833, 0.778, 0.87 ],
[ 0.979, 0.799, 0.461, 0.781],
[ 0.118, 0.64 , 0.143, 0.945],
[ 0.522, 0.415, 0.265, 0.774]])
现在我可以触发这两个表达式:
a[a>threshold] = upper
a[a<=threshold] = lower
实现我的目标:
array([[ 0., 1., 1., 1.],
[ 1., 1., 0., 1.],
[ 0., 1., 0., 1.],
[ 1., 0., 0., 1.]])
但有没有办法只用一个表达式来做到这一点?
答案 0 :(得分:27)
我们可能会考虑np.where
:
np.where(a>threshold, upper, lower)
Out[6]:
array([[0, 1, 1, 1],
[1, 1, 0, 1],
[0, 1, 0, 1],
[1, 0, 0, 1]])
答案 1 :(得分:5)
Numpy将每个1d数组视为向量,将2d数组视为向量序列(矩阵),将3d +数组视为通用张量。这意味着当我们执行操作时,我们正在执行矢量数学运算。所以你可以这样做:
>>> a = (a > 0.5).astype(np.int_)
例如:
>>> np.random.seed(0)
>>> np.set_printoptions(precision=3)
>>> a = np.random.rand(4, 4)
>>> a
>>> array([[ 0.549, 0.715, 0.603, 0.545],
[ 0.424, 0.646, 0.438, 0.892],
[ 0.964, 0.383, 0.792, 0.529],
[ 0.568, 0.926, 0.071, 0.087]])
>>> a = (a > 0.5).astype(np.int_) # Where the numpy magic happens.
>>> array([[1, 1, 1, 1],
[0, 1, 0, 1],
[1, 0, 1, 1],
[1, 1, 0, 0]])
这里发生的事情是,您将自动遍历4x4矩阵中每行的每个元素,并对每个元素应用布尔比较。
如果&gt; 0.5返回True,否则返回False。
然后通过调用 .astype 方法并传递 np.int _ 作为参数,你告诉numpy用它们的整数表示替换所有布尔值,实际上根据您的比较值对矩阵进行二值化。
答案 2 :(得分:2)
您可以直接编写表达式,这将返回一个布尔数组,它可以简单地用作1字节无符号整数(&#34; uint8&#34;)数组,以便进一步计算:
print a > 0.5
输出
[[False True True True]
[ True True False True]
[False True False True]
[ True False False True]]
在一行中,您可以使用自定义上/下值来编写,例如:
upper = 10
lower = 3
treshold = 0.5
print lower + (a>treshold) * (upper-lower)
答案 3 :(得分:2)
较短的方法是简单地将条件中的布尔矩阵乘以1或1.0,具体取决于您想要的类型。
>>> a = np.random.rand(4,4)
>>> a
array([[ 0.63227032, 0.18262573, 0.21241511, 0.95181594],
[ 0.79215808, 0.63868395, 0.41706148, 0.9153959 ],
[ 0.41812268, 0.70905987, 0.54946947, 0.51690887],
[ 0.83693151, 0.10929998, 0.19219377, 0.82919761]])
>>> (a>0.5)*1
array([[1, 0, 0, 1],
[1, 1, 0, 1],
[0, 1, 1, 1],
[1, 0, 0, 1]])
>>> (a>0.5)*1.0
array([[ 1., 0., 0., 1.],
[ 1., 1., 0., 1.],
[ 0., 1., 1., 1.],
[ 1., 0., 0., 1.]])