我正在尝试实现this answer中给出的解决方案,将我的~3.3GB ASCII读入ndarray
。
实际上,当我对我的文件使用此函数时,我得到MemoryError
:
def iter_loadtxt(filename, delimiter=None, skiprows=0, dtype=float):
def iter_func():
with open(filename, 'r') as infile:
for _ in range(skiprows):
next(infile)
for line in infile:
line = line.rstrip().split(delimiter)
for item in line:
yield dtype(item)
iter_loadtxt.rowlength = len(line)
data = np.fromiter(iter_func(), dtype=[('',np.float),('',np.float),('',np.float),('',np.int),('',np.int),('',np.int),('',np.int)])
data = data.reshape((-1, iter_loadtxt.rowlength))
return data
data = iter_loadtxt(fname,skiprows=1)
我现在正试图在np.fromiter
的调用中输入不同的dtypes,希望如果我的大多数列是整数而不是浮点数,我将有足够的运气来避免内存问题,但我没有到目前为止的成功。
我的文件是"很多行" X 7 cols,我想指定以下格式:前三个col的float
和以下uint
。我的操作系统是Windows 10 64位,我有8GB的RAM。我使用的是python 2.7 32bit。
我的尝试是(this answer之后):
data = np.fromiter(iter_func(), dtype=[('',np.float),('',np.float),('',np.float),('',np.int),('',np.int),('',np.int),('',np.int)])
但我收到TypeError: expected a readable buffer object
EDIT1
感谢提供解决方案的 hpaulj 。以下是工作代码。
def iter_loadtxt(filename, delimiter=None, skiprows=0, dtype=float):
def iter_func():
dtypes = [float, float, float, int, int, int, int]
with open(filename, 'r') as infile:
for _ in range(skiprows):
next(infile)
for line in infile:
line = line.rstrip().split(delimiter)
values = [t(v) for t, v in zip(dtypes, line)]
yield tuple(values)
iter_loadtxt.rowlength = len(line)
data = np.fromiter(iter_func(), dtype=[('',np.float),('',np.float),('',np.float),('',np.int),('',np.int),('',np.int),('',np.int)])
return data
data = iter_loadtxt(fname,skiprows=1)
答案 0 :(得分:1)
如果输入文件足够大,任何代码(无论如何简化)都会出现内存错误。
对于所有浮点数,您的7列数组将占用56个字节;与混合dtype 40.不完全是一个很大的变化。如果它之前通过文件的1/3击中内存错误,它现在会命中它(理论上是1/2)。
iter_func
读取文件,并提供稳定的浮动流(它自己的dtype)。它不返回按行分组的浮点数。它保留了一些行数,最后用它来重塑1d数组。
fromiter
可以处理复合dtype,但前提是它为它提供了适当大小的元组。
In [342]: np.fromiter([(1,2),(3,4),(5,6)],dtype=np.dtype('i,i'))
Out[342]:
array([(1, 2), (3, 4), (5, 6)],
dtype=[('f0', '<i4'), ('f1', '<i4')])
In [343]: np.fromiter([1,2,3,4],dtype=np.dtype('i,i'))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-343-d0fc5f822886> in <module>()
----> 1 np.fromiter([1,2,3,4],dtype=np.dtype('i,i'))
TypeError: a bytes-like object is required, not 'int'
将iter_func
更改为此类内容可能有效(未经测试):
def iter_func():
dtypes=[float,float,float,int,int,int,int]
with open(filename, 'r') as infile:
for _ in range(skiprows):
next(infile)
for line in infile:
line = line.rstrip().split(delimiter)
values = [t(v) for t,v in zip(dtypes, line)]
yield tuple(values)
arr = np.fromiter(iter_func, dtype=[('',np.float),('',np.float),('',np.float),('',np.int),('',np.int),('',np.int),('',np.int)] )