Python 用于绝对值的 numpy bool 掩码

Python numpy bool masks for absoluting values

假设你有一个 numpy array(n,n) 即。

    x = np.arange(25).reshape(5,5)

然后用 -5 到 5 之间的随机整数填充 x。有没有一种方法可以使用布尔掩码,以便我所有的 0 值都变成 1,所有非零的数字都变成零?(即, 如果 [index]>0 or [index]<0, [index]=0, 如果 [index]=0 then [index]=1)

我知道您可以使用迭代来更改每个元素,但我的目标是速度,因此我想从最终脚本中消除尽可能多的循环。

编辑:当然,只要牢记 speed/efficiency,也欢迎其他想法

您可以对此使用列表理解...

bool_x = [0 if y != 0 else 1 for y in x.reshape(25,1)]

如果您追求速度,请考虑是否真的需要将数组设为 5x5,然后进行转换,或者如果可以 np.arange(25),直接应用列表理解,然后重新整形。所有这些重塑肯定会让你付出一些代价。

首先你不需要使用reshape,你可以像这样直接创建你的随机矩阵:

M = np.random.randint(-5,5,(2,2))

然后如果你想做你的替换,你可以像这样做你的索引:

M[M==1]=10
M[M==0]=1
M[M==10]=0

首先,您可以直接使用 np.random.randint:

实例化您的数组
# Note: the lower limit is inclusive while the upper limit is exclusive
x = np.random.randint(-5, 6, size=(5, 5))

要真正完成工作,也许类型转换为 bool,类型转换回来,然后取反?

res = 1 - x.astype(bool).astype(int)

或者,您可以更明确一点:

x[x != 0] = 1
res = 1 - x

但第二种方法似乎花费了两倍多的时间:

>>> n = 1000
>>> a = np.random.randint(-5, 6, (n, n))
>>> %timeit a.astype(bool).astype(int)
1000 loops, best of 3: 1.58 ms per loop
>>> %timeit a[a != 0] = 1
100 loops, best of 3: 4.61 ms per loop

您可以使用与 0 的简单比较来为我们提供布尔数组,然后使用 +0 转换为 int 数据类型或使用 .astype(int) 进行类型转换。因此,我们将有两种方法。

方法 #1:

(x==0)+0

方法 #2:

(x==0).astype(int)

运行时测试

本节比较了前面提到的两种方法的运行时间,并包括 x 转换为布尔数据类型 -

案例 #1:

In [36]: x = np.arange(25).reshape(5,5)

In [37]: %timeit (x==0)+0
    ...: %timeit (x==0).astype(int)
    ...: %timeit 1 - x.astype(bool).astype(int)
    ...: 
1000000 loops, best of 3: 1.85 µs per loop
1000000 loops, best of 3: 1.08 µs per loop
1000000 loops, best of 3: 1.51 µs per loop

案例 #2:

In [38]: x = np.random.randint(0,50,(10000,10000))

In [39]: %timeit (x==0)+0
    ...: %timeit (x==0).astype(int)
    ...: %timeit 1 - x.astype(bool).astype(int)
    ...: 
1 loops, best of 3: 227 ms per loop
10 loops, best of 3: 186 ms per loop
1 loops, best of 3: 319 ms per loop

看来(x==0).astype(int)表现的不错!