Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么在numpy中,布尔运算比其他类型的运算慢?_Python_Numpy_Matrix_Time_Boolean - Fatal编程技术网

Python 为什么在numpy中,布尔运算比其他类型的运算慢?

Python 为什么在numpy中,布尔运算比其他类型的运算慢?,python,numpy,matrix,time,boolean,Python,Numpy,Matrix,Time,Boolean,我想在numpy模块中使用布尔矩阵而不是整数矩阵,因为我的一些矩阵只包含0和1。 所以,我想知道为什么不使用布尔矩阵来加速一些计算。 但实际上,布尔矩阵上的运算比浮点矩阵上的运算要长得多 例如: import numpy as np import time RM = np.random.rand(1000,1000) RM = (RM >= .5 )*1. start_time = time.time() R = np.sum(RM) print("--- %s seconds --

我想在numpy模块中使用布尔矩阵而不是整数矩阵,因为我的一些矩阵只包含0和1。 所以,我想知道为什么不使用布尔矩阵来加速一些计算。 但实际上,布尔矩阵上的运算比浮点矩阵上的运算要长得多 例如:

import numpy as np
import time 

RM = np.random.rand(1000,1000)
RM = (RM >= .5 )*1.

start_time = time.time()
R = np.sum(RM)
print("--- %s seconds ---" % (time.time() - start_time))


RM = RM.astype(np.bool)

start_time = time.time()
R = np.sum(RM)
print("--- %s seconds ---" % (time.time() - start_time))
对此作出回应:

--- 0.0010001659393310547 seconds ---
--- 0.002000093460083008 seconds ---
所以布尔矩阵使用了两倍的时间! 我想知道为什么会发生这种情况,是否存在一个解决办法

更新 正如一些评论所提到的,我计算时间执行的方式并不是最好的方式。 使用@Anis的方法,这里是新方法:

import numpy as np
import timeit

RMint = np.ones((1000,1000), dtype='int64')
RMbool = np.ones((1000,1000), dtype='bool')
RMfloat = np.ones((1000,1000), dtype='float64')

def test():
    global RM
    R = np.sum(RM)

if __name__ == '__main__':
    print("int64")
    RM= RMint
    print(timeit.timeit("test( )", number=1000, setup="from __main__ import test"))
    print("bool")
    RM= RMbool
    print(timeit.timeit("test( )", number=1000, setup="from __main__ import test"))
    print("float64")
    RM=RMfloat
    print(timeit.timeit("test( )", number=1000, setup="from __main__ import test"))
我只是从测试函数中得到矩阵初始化,因为矩阵的构建不是这里的重点。 通过这种方法,我得出了相同的结论:

int64
0.7555235163780709
bool
1.9191522692976613
float64
0.935670545406214

所以布尔运算比int或float运算长得多。但我不明白为什么?

不,布尔运算比其他运算快。5次运行后的平均剖面如下所示

dtype     Average
int64   4.66626188
bool    1.243509225
float64 5.220022027
我的代码是从@Anis修改而来的

import numpy as np
import timeit

def test(dtype):     
    R = np.sum(np.ones((1000,1000), dtype=dtype))

if __name__ == '__main__':
    dtype = 'int64'
    print(dtype)
    print(timeit.timeit(f"test('{dtype}')", number=1000, setup="from __main__ import test"))

    dtype = 'bool'
    print(dtype)
    print(timeit.timeit(f"test('{dtype}')", number=1000, setup="from __main__ import test"))

    dtype = 'float64'
    print(dtype)
    print(timeit.timeit(f"test('{dtype}')", number=1000, setup="from __main__ import test"))
使用的模块包括:

软件
版本

Python
3.4.5 64位

IPython
5.1.0

OS
Windows10

numpy
1.11.3


不,布尔运算比其他运算快。5次运行后的平均剖面如下所示

dtype     Average
int64   4.66626188
bool    1.243509225
float64 5.220022027
我的代码是从@Anis修改而来的

import numpy as np
import timeit

def test(dtype):     
    R = np.sum(np.ones((1000,1000), dtype=dtype))

if __name__ == '__main__':
    dtype = 'int64'
    print(dtype)
    print(timeit.timeit(f"test('{dtype}')", number=1000, setup="from __main__ import test"))

    dtype = 'bool'
    print(dtype)
    print(timeit.timeit(f"test('{dtype}')", number=1000, setup="from __main__ import test"))

    dtype = 'float64'
    print(dtype)
    print(timeit.timeit(f"test('{dtype}')", number=1000, setup="from __main__ import test"))
使用的模块包括:

软件
版本

Python
3.4.5 64位

IPython
5.1.0

OS
Windows10

numpy
1.11.3


根据我的经验,在布尔的N阵列上的操作与仅在uint8的N阵列上的操作相等(速度方面)。通常,如果使用其他数据类型,并且对它们执行相同的操作,则所用的时间更高

当然,这也取决于所执行的操作,例如,可能是numpy.sum强制布尔数组转换为int64,因此所用的时间与使用int64获得的时间相当(甚至略高)

事实上,使用非mod 2算法对两个布尔数组求和几乎没有意义,并且在可能的情况下,应该始终使用mod 2算法(and、OR、XOR等),这是布尔数组上几乎唯一可能的算法,而不必强制转换到其他(更麻烦的)类型

这与以下事实有关:bool和uint8的ndarrays在较低级别上基本相同。 事实上,它们占用的内存量相同:

>>>import sys
>>>import numpy as np 

>>>sys.getsizeof(np.array([True], dtype="bool"))
   Out: 97
>>>sys.getsizeof(np.array([1], dtype="uint8"))
   Out: 97
>>>sys.getsizeof(np.array([1], dtype="int64"))
   Out: 104
uint8和bool占用相同的内存量是因为x86系统(以及大多数ARM和其他嵌入式系统)上的最小可寻址内存量是8位字(1字节)。看

此后,我报告了支持我的主张的基准(numpy 1.13.3):

正如您所看到的,uint8和bool在这里几乎没有区别,而int64则慢得多。有趣的是,我发现np.add比bools上的np.logical\u xor更快。
实际上,np.add实际上执行元素或而不是元素XOR(即模2加法)。在bool数组上执行时,np.add和np.logical_或这两个操作是相同的,np.add返回bool数组。

根据我的经验,bool n数组上的操作与uint8的n数组上的操作相等(速度)。通常,如果使用其他数据类型,并且对它们执行相同的操作,则所用的时间更高

当然,这也取决于所执行的操作,例如,可能是numpy.sum强制布尔数组转换为int64,因此所用的时间与使用int64获得的时间相当(甚至略高)

事实上,使用非mod 2算法对两个布尔数组求和几乎没有意义,并且在可能的情况下,应该始终使用mod 2算法(and、OR、XOR等),这是布尔数组上几乎唯一可能的算法,而不必强制转换到其他(更麻烦的)类型

这与以下事实有关:bool和uint8的ndarrays在较低级别上基本相同。 事实上,它们占用的内存量相同:

>>>import sys
>>>import numpy as np 

>>>sys.getsizeof(np.array([True], dtype="bool"))
   Out: 97
>>>sys.getsizeof(np.array([1], dtype="uint8"))
   Out: 97
>>>sys.getsizeof(np.array([1], dtype="int64"))
   Out: 104
uint8和bool占用相同的内存量是因为x86系统(以及大多数ARM和其他嵌入式系统)上的最小可寻址内存量是8位字(1字节)。看

此后,我报告了支持我的主张的基准(numpy 1.13.3):

正如您所看到的,uint8和bool在这里几乎没有区别,而int64则慢得多。有趣的是,我发现np.add比bools上的np.logical\u xor更快。
实际上,np.add实际上执行元素或而不是元素XOR(即模2加法)。在布尔数组上执行时,np.add和np.logical\u或两个操作相同,np.add返回布尔数组。

您必须多次运行实验(在大型数据集上)才能得出结论。。。总的差异只有一毫秒。例如,进程可能暂时挂起,等等。此外,您应该使用像
timeit
这样的工具来计算CPU时间,而不是墙时间。可能相关,也可能不相关。对于布尔数组求和,应使用
np.count\u nonzero
。好吧,我承认我之前的回答没有抓住重点,你完全正确。我没有考虑分配所造成的开销,因为我认为这与操作相比是很小的。错。