【问题标题】:numpy array memory larger than expectednumpy 数组内存大于预期
【发布时间】:2018-11-22 09:48:29
【问题描述】:

我有一个大约 16GB 的文件 bad_orders.csv 被读入 58GB RAM 机器内的一个 numpy 数组。

ubuntu@ip-172-31-22-232:~/Data/Autoencoder_Signin/joined_signin_rel$ free -g
          total        used        free      shared  buff/cache   available
Mem:             58           0          58           0           0          58
Swap:             0           0           0

当我运行以下命令时,作业被反复杀死:

import numpy as np
arr = np.genfromtxt('bad_orders.csv', delimiter =',', missing_values='',dtype='float32')

终端显示它正在使用不成比例的内存:

ubuntu@ip-172-31-22-232:~$ free -g
          total        used        free      shared  buff/cache   available
Mem:             58          42          12           0           3          16
Swap:             0           0           0

然后我尝试从原始文件中采样 10000 行并检查内存使用情况:

In [7]: samples = np.genfromtxt('samples.csv',delimiter=',', 
missing_values='', dtype='float32')

In [8]: samples.nbytes
Out[8]: 16680000

示例 numpy 数组显示大小为 0.017GB。我的文件总共有大约 8M 行,所以如果内存使用量呈线性增长,大型 numpy 数组应该占用 13GB 内存。为什么我在读取整个文件时需要超过 50GB?

【问题讨论】:

  • 加载文件时的使用量将超过最终数组的使用量。有多少列? 2085? (每个项目 8 个字节,1000 行)。典型的线宽是多少?
  • 尝试使用 np.fromiter 的迭代器/生成器。可能会慢一些,但内存效率应该更高。如果您事先知道尺寸,那应该不会太糟糕。类似(map(float, row) for row in csv.reader(open('myfile.csv'))
  • 使用纯浮点数、没有缺失值和简单的分隔符,genfromtxt 可能是矫枉过正。当您需要使用标题字段名称并自动推导出字段dtypes时,它会更有用。
  • @hpaulj 总列数为417。我之所以使用genfromtxt是因为loadtxt无法处理缺失值,这种情况下我的缺失值是空字符串。
  • 请告诉我们发生了什么,您尝试过 pandas 吗?

标签: python arrays numpy memory


【解决方案1】:

genfromtxt 有很多类型检查,仅适用于小文件。对于较大的文件,您最好使用loadtxt,尽管仍然比here 提到的文件使用更多的内存。 另一个更好的方法是使用 pandas 的read_csv

【讨论】:

  • 我认为genfromtxtloadtxt 都在列表列表中收集数据,csv 文件的每一行都有一个子列表。 genfromtxt 可能会做更多检查,但我认为这不会改变内存使用情况。但我并没有考虑到这一点来检查两者的代码。
  • @hpaulj 检查我提供的链接。他们已经进行了速度测试,并解释了为什么速度较慢。根据此链接,Pandas 更快:akuederle.com/stop-using-numpy-loadtxt。我还没有对其进行内存分析,但我认为由于它是为大数据设计的,因此内存效率也应该更高。
  • pandas 有两种模式,编译速度更快,Python 版本更慢,功能更多。
  • 主要区别似乎是loadtxt 以50,000 行块加载文件,并使用指定的dtype 转换字符串。 genfromtxt 拆分所有行,并进行一次 dtype 转换,可能使用它推导出的 dtype。
猜你喜欢
  • 2019-02-18
  • 2023-04-01
  • 1970-01-01
  • 2020-01-25
  • 2014-08-16
  • 2019-11-09
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
相关资源
最近更新 更多