【问题标题】:Why does this python list need so much more memory?为什么这个 python 列表需要这么多内存?
【发布时间】:2017-08-22 00:08:06
【问题描述】:

我想在 python 中创建一个 numpy 数组列表。数组大多为零,很少有标志设置为 1。

在运行以下代码时,我遇到了内存问题。该代码需要〜我期望它使用的内存的两倍。

Python 循环填充列表:

vectorized_data = []
os.system("free -m")
for dat in data: #data has length 200000
    one_hot_vector = np.zeros(6000)
    for d in dat:
        one_hot_vector[d] = 1
    vectorized_data.append(one_hot_vector)
os.system("free -m") ##memory usage goes up by ~7.5GB

我希望这段代码使用的内存量(向量维度:6000,#samples:200000,numpy 浮点字节:4):

(6000 * 200000 * 4) /(2**30.0) ~= 4.47 GB

实际使用的内存量:

~7.5 GB

有没有更节省内存的方法来实现这一点?

【问题讨论】:

  • 如果我理解正确的话,datavectorized_data 都被保存在内存中。
  • @jmunsch 是正确的。
  • np.zeros(6000).dtype == dtype('float64')np.dtype(np.float64).itemsize == 8 (至少在我的电脑上) - 这可以解释你乘以错误数字的大小差异,它们是 8 个字节而不是 4 个字节。也许你需要np.zeros(6000, np.float32)(或np.int32)。
  • 一个数组必须存储它的所有值,而不仅仅是您更改的值。我不知道文档中的引用与此有什么关系。
  • data 是列表还是数组?如果数组data[:20000] 没有复制。

标签: python numpy memory one-hot-encoding


【解决方案1】:

可以使用生成器和行/列 ID,例如:

def yield_row(data):
  for r_id, dat in enumerate(data):
      tmp = np.zeros(6000)
      for d in dat:
          tmp[d] = 1
      yield r_id, tmp

for r_id, tmp in yield_row(data):
  if is_hot_vector(tmp):
    do_stuff()

这种方法的缺点是只能访问行/列 id 和当前 tmp 行,但是它将所需的内存量减少到 data 加上一行。

另一种方法可能是仅将行 ID 添加到列表中而不是整个行,只需索引该行,如果需要添加翻译/转换。

【讨论】:

    猜你喜欢
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 2017-05-22
    相关资源
    最近更新 更多