python - NumPy 的字符串数组的内存使用量远大于对象数组
问题描述
我还是 Numpy 的新手,并且正在搞乱 Numpy 的dtypes,发现特定于字符串的 dtype,也就是 'U',比对象类型占用更多的内存空间。说明这一事实的代码如下:
size= 100000
half_size = size//2
ind1 = np.arange(half_size)*2+1
ind2 = np.arange(half_size)*2
X = np.empty(size, dtype = 'object')
X[ind1] = 'smile'
X[ind2] = 'smile2'
W = np.empty(size, dtype = 'U6')
W[ind1] = 'smile'
W[ind2] = 'smile2'
print(X.nbytes)
print(W.nbytes)
结果如下:
800000
2400000
我的问题如下:
1)为什么会发生这种情况?为什么 dtype = 'U6' 占用的内存是 dtype = object 的 3 倍
2) 有没有办法创建一个比 dtype = object 占用更少内存空间的字符串 numpy 数组?
先感谢您
编辑:我想解释一下我的帖子不是另一篇帖子的重复,因为我的帖子是关于内存使用的,而另一篇帖子没有提到任何关于 dtype = 'U' vs dtype = 'object 的内存使用情况'
EDIT2:虽然我已经从另一篇文章中学到了一些新东西,但不幸的是,另一篇文章没有回答我的问题,因为我的文章是关于内存使用的,而另一篇文章没有提到关于 dtype = 'U' vs 的内存使用的任何内容dtype = '对象'
解决方案
sys.getsizeof
是检查内存使用情况的一种方法,尽管您必须明智地使用它,了解它到底在测量什么。对于数组,它工作得相当好。
没有任何元素的数组:
In [28]: sys.getsizeof(np.array([],'U6'))
Out[28]: 96
In [29]: sys.getsizeof(np.array(['smile','smile1'],'U6'))
Out[29]: 144
In [30]: sys.getsizeof(np.array(['smile','smile1'],'S6'))
Out[30]: 108
使用 2 个“U6”字符串,大小跳跃 48,4 个字节/字符 *2 个元素 *6 个字符/元素
使用 bytestring dtype(Py2 的默认值),跳转为 12、2*6。
bytestring 更紧凑,但请注意显示:
In [31]: np.array(['smile','smile1'],'S6')
Out[31]: array([b'smile', b'smile1'], dtype='|S6')
对于对象 dtype:
In [32]: sys.getsizeof(np.array(['smile','smile1'],object))
Out[32]: 112
那是 16 个字节 - 2*8
但是加上 Python 字符串的大小,额外的 133 个字节
In [33]: sys.getsizeof('smile')
Out[33]: 78
In [34]: sys.getsizeof('smile1')
Out[34]: 55
对于字节环:
In [36]: sys.getsizeof(b'smile')
Out[36]: 38
In [37]: sys.getsizeof(b'smile1')
Out[37]: 39
请注意,当我添加一个字节字符时,大小会增加 1。但是当我添加一个 unicode 字符时,大小实际上会减小。unicode 字符串的大小更难预测。我认为它最多可以为每个字符分配 4 个字节,但实际数量取决于字符和编码。通常我们不会尝试对 Python 的字符串处理进行微管理。(除此之外,我相信 Python 有某种字符串缓存。)
但是当你分配
X[ind1] = 'smile'
X[ind2] = 'smile2'
在对象情况下,您创建两个 Python 字符串,并将引用(指针)分配给数组。所以内存使用量是数组(1000...*8 字节)加上这 2 个字符串的 133 字节。
在 'U6' 的情况下,每个元素占用 4*6 字节,无论它是 'smile' 还是 'smile1'(或 's')。数组的每个元素都使用相同的空间,无论是否需要所有元素来表示字符串。
一般来说,弦乐不是一种numpy
力量。当字符串具有相似的大小时,'U' 或 'S' dtype 的内存使用是可以的,但如果字符串的长度不同、重复和/或是 unicode,则不太理想。 numpy
不做太多自己的字符串处理。这些np.char
函数只是 Python 字符串方法的薄包装。
pandas
已选择使用object
dtype 而不是字符串 dtypes。
推荐阅读
- java - 如何将 iText5 代码段正确翻译为 iText7?
- r - 在 R data.table 中,使用 .SD 时在 j 中使用 dot(.) 和 'c' 有什么区别?它是如何工作的?
- javascript - 没有响应头 Access-Control-Allow-Origin 时允许 CORS
- java - 循环变量java android studio
- sql - Oracle SQL ORA-00600:GREATEST 和 regexp_replace 子查询出错
- android - 通过使我的应用程序成为 homeScreen 应用程序来禁用主页按钮
- java - Java 时间:创建自己的时区
- python - 鉴于所有多边形都是一个分区,我如何快速查找包含一个点的多边形?
- jenkins - Jenkins 扩展电子邮件无法发送带附件的电子邮件
- java - 为什么json不显示列表中的对象?