【问题标题】:Why does str array and object array of same data are different wrt memory usage?为什么相同数据的 str 数组和 object 数组的内存使用量不同?
【发布时间】:2020-04-26 10:54:05
【问题描述】:

我有大量文本及其相应标签的数据集。我曾经使用 csv 模块读取 csv 文件,然后在该数据上构建 numpy 数组,直到我发现 numpy 中的大型文本数组内存效率低下。

with open('sample.csv', 'r') as f: 
    data = csv.reader(f.readlines())                                                                                                                                             

texts = np.array([d[0] for d in data])

这需要大约 13GB 内存。但是当pandas 读取相同的数据时,就像什么都没发生一样,内存中没有数据。我的意思是,它的内存使用量并没有减少 50% 甚至 20%,它只需要 300 MB 的内存。

data = pd.read_csv('sample.csv')

texts2 = np.array(data['text'])

textstexts2 数组之间的唯一区别是 dtype:

texts.dtype
dtype('<U92569')

texts2.dtype
dtype('O')

【问题讨论】:

  • 'U92569' dtype 表示 numpy 数组为每个元素分配 92569 个字符(每个 4 个字节)(我怀疑每行一个元素)。使用texts.shape,我们可以计算内存使用量。那 92569 是最长字符串的长度。你看过texts的元素吗?
  • @hpaulj 文本元素是一些可变大小的 cmets。

标签: python pandas numpy


【解决方案1】:

您的第一个数组使用 NumPy 字符串 dtype。这些是固定宽度的,因此数组的每个元素占用的空间与数组中最长的字符串一样多,其中一个字符串的长度为 92569 个字符,从而提高了较短字符串的空间需求。

您的第二个数组正在使用 object dtype。这只包含对一堆常规 Python 对象的引用,因此每个元素都是一个常规 Python 字符串对象。每个元素都有额外的对象开销,但每个字符串只需要足够的空间来保存自己的数据,而不是足够的空间来保存数组中最大的字符串。

此外,NumPy unicode dtypes 总是每个字符使用 4 个字节,而如果字符串不包含任何高代码点,则 Python 字符串对象使用较少。

【讨论】:

  • 我尝试在数据框中对numpy 字符串及其对应的对象列执行 memory_profile,我可以可视化您的答案,有趣的是,当我操作该列以使所有字符串都属于相同的长度,numpy 字符串似乎比 pandas 数据帧占用的内存少得多。如果所有字符串的长度相同,它似乎在内存方面得到了极大的优化。
猜你喜欢
  • 2020-03-06
  • 2017-04-30
  • 2018-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-25
  • 2021-12-02
  • 1970-01-01
相关资源
最近更新 更多