非常大的阵列处理与astropy和numpy

时间:2017-04-25 12:39:21

标签: arrays list numpy astropy

由于某些原因,我需要使用astropy将计算距离转换为红移。基本上这涉及读入,循环和写出列表或numpy数组......我的问题是我的每个列表通常由~9.5 x 10 ^ 6个元素组成。每当我尝试使用numpy.savetxt将输出保存到新的txt文件时,这就给了我MemoryError。内存使用量迅速增长,最终减慢一点,但总是高于我的128Gb限制。

如果有人知道如何改进下面的脚本,我非常愿意倾听。谢谢!

import os
import sys
import glob
import math
import numpy
import astropy
import astropy.units as unit
from astropy.cosmology import *
cosmo = FlatLambdaCDM(H0=70, Om0=0.3)

inFile=sys.argv[1]
outFile=sys.argv[2]

comovingDistance = numpy.loadtxt(inFile, usecols=(2,))

Redshift = numpy.zeros(len(comovingDistance)) 
for i in range(len(comovingDistance)):
    Redshift[i] = z_at_value(cosmo.comoving_distance, comovingDistance[i] * unit.kpc)

output = open(outFile,'w')
numpy.savetxt(output, Redshift, fmt='%1.8e')
output.close()

以下是错误日志文件:

Traceback (most recent call last):
  File "comoving2redshift.py", line 21, in <module>
    Redshift[i] = z_at_value(cosmo.comoving_distance, comovingDistance[i] * unit.kpc)
  File "/afs/mpa/home/minh/.local/lib/python2.7/site-packages/astropy/cosmology/funcs.py", line 119, in z_at_value
    fval_zmax = func(zmax)
  File "/afs/mpa/home/minh/.local/lib/python2.7/site-packages/astropy/cosmology/core.py", line 1195, in comoving_distance
    return self._comoving_distance_z1z2(0, z)
  File "/afs/mpa/home/minh/.local/lib/python2.7/site-packages/astropy/cosmology/core.py", line 1219, in _comoving_distance_z1z2
    return self._hubble_distance * vectorize_if_needed(f, z1, z2)
  File "/afs/mpa/home/minh/.local/lib/python2.7/site-packages/astropy/units/quantity.py", line 924, in __mul__
    return super(Quantity, self).__mul__(other)
  File "/afs/mpa/home/minh/.local/lib/python2.7/site-packages/astropy/units/quantity.py", line 368, in __array_prepare__
    from .quantity_helper import UNSUPPORTED_UFUNCS, UFUNC_HELPERS
MemoryError

2 个答案:

答案 0 :(得分:1)

我不知道numpy固有的任何解决方案,但是你可以通过将每个解决方案及时写入文件而不是for循环来节省一些内存分配。这节省了Redshift的内存分配以及numpy.savetxt()将浮点数格式化为字符串后幕后完成的内存分配。

inFile=sys.argv[1]
outFile=sys.argv[2]

comovingDistance = numpy.loadtxt(inFile, usecols=(2,))

with open(outFile, 'w') as fp:
    for distance in comovingDistance:
        fp.write("{:1.8e}\n".format(
            z_at_value(cosmo.comoving_distance, distance * unit.kpc)))

(注意:未经测试)

答案 1 :(得分:1)

作为我的其他建议解决方案的替代方案,您可以拆分输入文件,迭代新的(临时)输入文件集,并在最后连接输入文件。 下面是一个bash包装器脚本,在外部,应该与问题中的Python脚本相同(一个输入文件参数,一个输出文件参数)。

emulator: command not found

您可能希望使用临时目录,而不是依赖于唯一的前缀。