我仍然是numpy的新手,并且在numpy的dtypes周围搞砸了,发现针对字符串(aka'U'(的dtype比对象类型所使用的存储空间更多。说明这一事实的代码下面是:
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'占记忆的3倍,是dtype = object
2(是否有一种方法可以创建一个字符串numpy数组,该字符串占用的存储空间比dtype =对象少?
预先感谢您
编辑:我想解释说我的帖子不是另一帖的副本,因为我的帖子是关于内存使用的,而另一篇文章没有提及有关dtype ='u'vs dtype的内存使用情况的任何内容='对象'
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个字节/char *2元素 *6个char
使用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
和bytestsrings:
In [36]: sys.getsizeof(b'smile')
Out[36]: 38
In [37]: sys.getsizeof(b'smile1')
Out[37]: 39
请注意,当我添加字节字符时,大小会增加1。但是当我添加一个Unicode字符时,大小实际上会减小。Unicode字符串的大小更难预测。我认为它最多可以分配4个字节,但实际数字取决于字符和编码。通常,我们不会尝试微型Mange Python的字符串处理。(最重要的是,我相信Python有某种字符串缓存。(
但是当您分配
时X[ind1] = 'smile'
X[ind2] = 'smile2'
在对象情况下,您可以制作两个python字符串,并将引用(指针(分配给数组。因此,内存使用量是数组(1000 ...*8字节(加上这两个字符串的133个字节。
在" u6"情况下,每个元素都占用4*6字节,无论是"微笑"还是" smile1"(或" s"(。数组的每个元素都使用相同的空间,而不管是否需要所有这些空间来表示字符串。
总体字符串不是numpy
强度。当字符串的大小相似,如果字符串的长度变化,重复和/或是Unicode时," U"或" S" dtype的内存使用情况还可以。numpy
不做自己的字符串处理太多。np.char
功能只是Python String方法的薄包装器。
pandas
选择使用object
dtype而不是字符串dtypes。
如果您查看内存中的每种数据类型的大小:
import numpy as np
dt = np.dtype('object')
print('object = %i bytes' % dt.itemsize)
dt = np.dtype('U6')
print('U6 = %i bytes' % dt.itemsize)
输出:
object = 8 bytes
U6 = 24 bytes