Numba 的最佳可能位数组
Best possible bit array for Numba
我需要在 Python 中创建一个位数组。到目前为止,我发现可以使用 bitarray 模块生成非常节省内存的数组。
但是,我的最终目的是使用 Numba. Numba works with only a limited amount of Python and numpy 功能中的 @vectorize
装饰器,而位数组不是其中之一。
我的问题是,使用 Numba 支持的结构创建位数组的最佳内存效率方式是什么?
我会选择 numpy 数组,但我做了一个快速的内存测试,结果看起来不太好:
>>> import numpy as np
>>> import random
>>> from bitarray import bitarray
>>> from sys import getsizeof
>>> N = 10000
>>> a = bitarray(N)
>>> print(type(a), getsizeof(a))
<class 'bitarray.bitarray'> 96
>>> b = np.random.randint(0, 1, N)
>>> print(type(b), b.nbytes)
<class 'numpy.ndarray'> 40000
>>> c = [random.randint(0, 1) for i in range(N)]
>>> print(type(c), getsizeof(c))
<class 'list'> 87624
(更不用说list
)
编辑:作为附带问题,有没有人知道为什么 getsizeof
returns bitarray
的数字如此低得不切实际?我刚注意到。
您可以简单地指定数据类型:
N=1000
b = np.random.randint(0, 1, N)
print(type(b),getsizeof(b))
<class 'numpy.ndarray'> 4096
c = np.random.randint(0, 1, N, dtype=np.bool)
print(type(b),getsizeof(c))
<class 'numpy.ndarray'> 1096
对于你的附带问题,numpy 在 numpy 对象中构造的比 bitarrray 多得多,因此它在对象的总内存方面效率较低。
编辑:
python中对象的内存由对象中实现的所有方法组成,至少是它们对代码、属性和项的引用,例如object.size
,它是numpy中的一个元组由整数等组成。在您的列表中,您有多个对方法的引用,例如pop
、delete
等,它由排列在不同节点中的整数组成(列表是a的扩展实现经典链表结合其他方法,参见官方文档data structures)。
考虑到所有这些因素,最佳做法是使用适合您的管道的适当数据结构,并尽可能指定类型。由于您使用 numba
,numpy 似乎是最合适的。内存并不总是问题。
我需要在 Python 中创建一个位数组。到目前为止,我发现可以使用 bitarray 模块生成非常节省内存的数组。
但是,我的最终目的是使用 Numba. Numba works with only a limited amount of Python and numpy 功能中的 @vectorize
装饰器,而位数组不是其中之一。
我的问题是,使用 Numba 支持的结构创建位数组的最佳内存效率方式是什么?
我会选择 numpy 数组,但我做了一个快速的内存测试,结果看起来不太好:
>>> import numpy as np
>>> import random
>>> from bitarray import bitarray
>>> from sys import getsizeof
>>> N = 10000
>>> a = bitarray(N)
>>> print(type(a), getsizeof(a))
<class 'bitarray.bitarray'> 96
>>> b = np.random.randint(0, 1, N)
>>> print(type(b), b.nbytes)
<class 'numpy.ndarray'> 40000
>>> c = [random.randint(0, 1) for i in range(N)]
>>> print(type(c), getsizeof(c))
<class 'list'> 87624
(更不用说list
)
编辑:作为附带问题,有没有人知道为什么 getsizeof
returns bitarray
的数字如此低得不切实际?我刚注意到。
您可以简单地指定数据类型:
N=1000
b = np.random.randint(0, 1, N)
print(type(b),getsizeof(b))
<class 'numpy.ndarray'> 4096
c = np.random.randint(0, 1, N, dtype=np.bool)
print(type(b),getsizeof(c))
<class 'numpy.ndarray'> 1096
对于你的附带问题,numpy 在 numpy 对象中构造的比 bitarrray 多得多,因此它在对象的总内存方面效率较低。
编辑:
python中对象的内存由对象中实现的所有方法组成,至少是它们对代码、属性和项的引用,例如object.size
,它是numpy中的一个元组由整数等组成。在您的列表中,您有多个对方法的引用,例如pop
、delete
等,它由排列在不同节点中的整数组成(列表是a的扩展实现经典链表结合其他方法,参见官方文档data structures)。
考虑到所有这些因素,最佳做法是使用适合您的管道的适当数据结构,并尽可能指定类型。由于您使用 numba
,numpy 似乎是最合适的。内存并不总是问题。