用于绝对值的Python numpy bool掩码

时间:2015-06-05 00:04:54

标签: python arrays numpy indexing masking

假设你有一个numpy数组(n,n)即

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

并用-5和5之间的随机整数填充x。是否有一种方法可以使用布尔掩码,以便所有0的值变为1,并且所有非零的数字变为零?(即,如果[index]> 0或[index]< 0,[index] = 0,如果[index] = 0则[index] = 1)

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

编辑:当然,只要记住速度/效率,就可以接受其他想法

4 个答案:

答案 0 :(得分:2)

首先,您可以使用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

答案 1 :(得分:2)

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

方法#1:

(x==0)+0

方法#2:

(x==0).astype(int)

运行时测试

本节比较前面提到的两种方法的运行时,并包括other numpy array based approachx转换为布尔数据类型 -

案例#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)表现得相当好!

答案 2 :(得分:0)

你可以使用列表理解...

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

如果你想要速度,但考虑一下你是否真的需要数组是5x5,然后转换,或者你可以np.arange(25),直接应用列表推导然后重塑。所有重塑都会让你付出一定的代价。

答案 3 :(得分:0)

首先,您不需要使用重塑,您可以像这样直接创建随机矩阵:

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

然后,如果您想进行替换,您可以像这样进行索引:

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