Python 逻辑与乘法
给定三个Python 逻辑与乘法,python,arrays,numpy,boolean,boolean-operations,Python,Arrays,Numpy,Boolean,Boolean Operations,给定三个numpy数组a、b和c(编辑:形状/大小相同),对于非复数,似乎 a * b * c != 0 # test element-wise whether all are non-zero 给出与以下相同的结果: np.logical_and(a, np.logical_and(b, c)) 第一个版本中有隐藏的陷阱吗?有没有更简单的方法来测试这一点?它们是一样的。0且无一为假;任何其他值均为True。但是,逻辑测试速度更快。如果列表中有很多数组,请考虑使用Python的所有< /强
numpy
数组a
、b
和c
(编辑:形状/大小相同),对于非复数,似乎
a * b * c != 0 # test element-wise whether all are non-zero
给出与以下相同的结果:
np.logical_and(a, np.logical_and(b, c))
第一个版本中有隐藏的陷阱吗?有没有更简单的方法来测试这一点?它们是一样的。0且无一为假;任何其他值均为True。但是,逻辑测试速度更快。如果列表中有很多数组,请考虑使用Python的<强>所有< /强>和<强>任何< /强>方法。< /P>
例如:
for value in [True, False, 0, 1, None, 7, 'a', [False, False, False]]:
if value:
print value, True
else:
print value, False
输出:
True True
False False
0 False
1 True
None False
7 True
a True
[False, False, False] True
假设
b
和c
持有实数,np.logical_和(b,c)
将本质上涉及到从底层到布尔数的转换
我们可以提前做转换吗?如果是,那会有帮助吗
现在,检查所有
对应元素是否为非零的所述操作将等同于检查相应元素的任何
的布尔值是否为零,即
~((a==0)+(b==0)+(c==0)
或
~((a==0)|(b==0)|(c==0))
此外,这还需要在与zero
进行比较后将其预先转换为布尔值,这样可能有助于提高性能-
案例1:
In [10]: # Setup inputs
...: M, N = 100, 100
...: a = np.random.randint(0,5,(M,N))
...: b = np.random.randint(0,5,(M,N))
...: c = np.random.randint(0,5,(M,N))
...:
In [11]: %timeit np.logical_and(a, np.logical_and(b, c))
...: %timeit a * b * c != 0
...: %timeit ~((a == 0) + (b==0) + (c==0))
...: %timeit ~((a == 0) | (b==0) | (c==0))
...:
10000 loops, best of 3: 96.6 µs per loop
10000 loops, best of 3: 78.2 µs per loop
10000 loops, best of 3: 51.6 µs per loop
10000 loops, best of 3: 51.5 µs per loop
In [12]: # Setup inputs
...: M, N = 1000, 1000
...: a = np.random.randint(0,5,(M,N))
...: b = np.random.randint(0,5,(M,N))
...: c = np.random.randint(0,5,(M,N))
...:
In [13]: %timeit np.logical_and(a, np.logical_and(b, c))
...: %timeit a * b * c != 0
...: %timeit ~((a == 0) + (b==0) + (c==0))
...: %timeit ~((a == 0) | (b==0) | (c==0))
...:
100 loops, best of 3: 11.4 ms per loop
10 loops, best of 3: 24.1 ms per loop
100 loops, best of 3: 9.29 ms per loop
100 loops, best of 3: 9.2 ms per loop
In [14]: # Setup inputs
...: M, N = 5000, 5000
...: a = np.random.randint(0,5,(M,N))
...: b = np.random.randint(0,5,(M,N))
...: c = np.random.randint(0,5,(M,N))
...:
In [15]: %timeit np.logical_and(a, np.logical_and(b, c))
...: %timeit a * b * c != 0
...: %timeit ~((a == 0) + (b==0) + (c==0))
...: %timeit ~((a == 0) | (b==0) | (c==0))
...:
1 loops, best of 3: 294 ms per loop
1 loops, best of 3: 694 ms per loop
1 loops, best of 3: 268 ms per loop
1 loops, best of 3: 268 ms per loop
案例2:
In [10]: # Setup inputs
...: M, N = 100, 100
...: a = np.random.randint(0,5,(M,N))
...: b = np.random.randint(0,5,(M,N))
...: c = np.random.randint(0,5,(M,N))
...:
In [11]: %timeit np.logical_and(a, np.logical_and(b, c))
...: %timeit a * b * c != 0
...: %timeit ~((a == 0) + (b==0) + (c==0))
...: %timeit ~((a == 0) | (b==0) | (c==0))
...:
10000 loops, best of 3: 96.6 µs per loop
10000 loops, best of 3: 78.2 µs per loop
10000 loops, best of 3: 51.6 µs per loop
10000 loops, best of 3: 51.5 µs per loop
In [12]: # Setup inputs
...: M, N = 1000, 1000
...: a = np.random.randint(0,5,(M,N))
...: b = np.random.randint(0,5,(M,N))
...: c = np.random.randint(0,5,(M,N))
...:
In [13]: %timeit np.logical_and(a, np.logical_and(b, c))
...: %timeit a * b * c != 0
...: %timeit ~((a == 0) + (b==0) + (c==0))
...: %timeit ~((a == 0) | (b==0) | (c==0))
...:
100 loops, best of 3: 11.4 ms per loop
10 loops, best of 3: 24.1 ms per loop
100 loops, best of 3: 9.29 ms per loop
100 loops, best of 3: 9.2 ms per loop
In [14]: # Setup inputs
...: M, N = 5000, 5000
...: a = np.random.randint(0,5,(M,N))
...: b = np.random.randint(0,5,(M,N))
...: c = np.random.randint(0,5,(M,N))
...:
In [15]: %timeit np.logical_and(a, np.logical_and(b, c))
...: %timeit a * b * c != 0
...: %timeit ~((a == 0) + (b==0) + (c==0))
...: %timeit ~((a == 0) | (b==0) | (c==0))
...:
1 loops, best of 3: 294 ms per loop
1 loops, best of 3: 694 ms per loop
1 loops, best of 3: 268 ms per loop
1 loops, best of 3: 268 ms per loop
案例3:
In [10]: # Setup inputs
...: M, N = 100, 100
...: a = np.random.randint(0,5,(M,N))
...: b = np.random.randint(0,5,(M,N))
...: c = np.random.randint(0,5,(M,N))
...:
In [11]: %timeit np.logical_and(a, np.logical_and(b, c))
...: %timeit a * b * c != 0
...: %timeit ~((a == 0) + (b==0) + (c==0))
...: %timeit ~((a == 0) | (b==0) | (c==0))
...:
10000 loops, best of 3: 96.6 µs per loop
10000 loops, best of 3: 78.2 µs per loop
10000 loops, best of 3: 51.6 µs per loop
10000 loops, best of 3: 51.5 µs per loop
In [12]: # Setup inputs
...: M, N = 1000, 1000
...: a = np.random.randint(0,5,(M,N))
...: b = np.random.randint(0,5,(M,N))
...: c = np.random.randint(0,5,(M,N))
...:
In [13]: %timeit np.logical_and(a, np.logical_and(b, c))
...: %timeit a * b * c != 0
...: %timeit ~((a == 0) + (b==0) + (c==0))
...: %timeit ~((a == 0) | (b==0) | (c==0))
...:
100 loops, best of 3: 11.4 ms per loop
10 loops, best of 3: 24.1 ms per loop
100 loops, best of 3: 9.29 ms per loop
100 loops, best of 3: 9.2 ms per loop
In [14]: # Setup inputs
...: M, N = 5000, 5000
...: a = np.random.randint(0,5,(M,N))
...: b = np.random.randint(0,5,(M,N))
...: c = np.random.randint(0,5,(M,N))
...:
In [15]: %timeit np.logical_and(a, np.logical_and(b, c))
...: %timeit a * b * c != 0
...: %timeit ~((a == 0) + (b==0) + (c==0))
...: %timeit ~((a == 0) | (b==0) | (c==0))
...:
1 loops, best of 3: 294 ms per loop
1 loops, best of 3: 694 ms per loop
1 loops, best of 3: 268 ms per loop
1 loops, best of 3: 268 ms per loop
与零比较法相比,似乎有很大比例的益处
!一些观察结果:
import numpy as np
import timeit
a = np.random.randint(0, 5, 100000)
b = np.random.randint(0, 5, 100000)
c = np.random.randint(0, 5, 100000)
method_one = np.logical_and(np.logical_and(a, b), c)
%timeit np.logical_and(np.logical_and(a, b), c)
method_two = a*b*c != 0
%timeit a*b*c != 0
method_three = np.logical_and(np.logical_and(a.astype('bool'), b.astype('bool')), c.astype('bool'))
%timeit np.logical_and(np.logical_and(a.astype('bool'), b.astype('bool')), c.astype('bool'))
method_four = a.astype('bool') * b.astype('bool') * c.astype('bool') != 0
%timeit a.astype('bool') * b.astype('bool') * c.astype('bool') != 0
# verify all methods give equivalent results
all([
np.all(method_one == method_two),
np.all(method_one == method_three),
np.all(method_one == method_four)
]
)
一些解释:
a*b*c!=0
方法的速度将取决于向量的dtype
,因为乘法是首先完成的。因此,如果你有浮点数、bigint或其他更大的dtype,这一步将比相同长度的布尔或小整数向量所需的时间更长。强制为bool
dtype加快了此方法的速度。如果向量具有不同的数据类型,则速度会更慢。将整数数组乘以浮点数组需要将整数转换为浮点,然后强制转换为布尔值。这不是最优的logical_and()
方法中强制布尔值的方式比使用.asdtype('bool')
慢np.logical\u和()
给出一个简短的总结:
a*b*c!=0
可能会导致溢出或下溢。另一种方法是~((a==0)|(b==0)|(c==0))
似乎比任何其他测试实现都执行得更快。这在Python 2.7和3.4中对我有效。我猜这个示例来自于a(非常?)使用固定整数表示的旧Python版本?不,它的工作原理与最新版本的Python类似。您很可能使用Python内置整数而不是NumPy数据类型运行测试。a=b=c=NumPy.array([2**16]);a*b*c!=0
在我的任何Python中都可以正常工作,正如我所期望的,而不是如链接中所示。那么陷阱在哪里?其他陷阱是什么?请使用numpy.array([2**24])尝试一下
,那么。可能您的默认值是64位整数。这里的陷阱是NumPy整数是固定宽度的,在溢出时包装,不像Python的无溢出bignum。由于nan和underflow,您会遇到类似的浮点数据问题;例如,a=b=NumPy.array([NumPy.nan])
和c=NumPy.array([0.0])
“0和None都是False;任何其他值都是True”-什么?不。在Python中,将值解释为布尔值不是这样工作的。