ste*_*esu 12 python memory csv file-io numpy
我有一个250 MB的CSV文件,我需要阅读~7000行和~9000列.每行代表一个图像,每列是一个像素(灰度值0-255)
我从一个简单的开始,np.loadtxt("data/training_nohead.csv",delimiter=",")
但这给了我一个内存错误.我认为这很奇怪,因为我正在运行64位Python,安装了8个内存,并且在仅使用大约512 MB后就死了.
我从那以后尝试了其他几种策略,包括:
import fileinput
并一次读取一行,将它们附加到数组中np.fromstring
读完整个文件后np.genfromtext
每种方法都给了我相同的结果.MemoryError大约512 MB.想知道是否有一些特殊的512MB,我创建了一个简单的测试程序,它填满了内存,直到python崩溃:
str = " " * 511000000 # Start at 511 MB
while 1:
str = str + " " * 1000 # Add 1 KB at a time
Run Code Online (Sandbox Code Playgroud)
这样做直到大约1演出才崩溃.我也是,只是为了好玩,试过:( str = " " * 2048000000
填2场演出) - 这顺便跑了.填写RAM,从不抱怨.所以问题不在于我可以分配的RAM总量,而是似乎是我可以分配内存的TIMES数量......
在我发现这篇文章之前,我无聊地google'd:Python大文件上的内存不足(numpy)
我完全复制了答案中的代码:
def iter_loadtxt(filename, delimiter=',', 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=dtype)
data = data.reshape((-1, iter_loadtxt.rowlength))
return data
Run Code Online (Sandbox Code Playgroud)
iter_loadtxt("data/training_nohead.csv")
这次调用给出了稍微不同的错误:
MemoryError: cannot allocate array memory
Run Code Online (Sandbox Code Playgroud)
谷歌搜索这个错误我只找到一个,不是那么有用,发布:内存错误(MemoryError)创建一个布尔NumPy数组(Python)
当我运行Python 2.7时,这不是我的问题.任何帮助,将不胜感激.
在@JF Sebastian 的帮助下,我得出了以下答案:
train = np.empty([7049,9246])
row = 0
for line in open("data/training_nohead.csv")
train[row] = np.fromstring(line, sep=",")
row += 1
Run Code Online (Sandbox Code Playgroud)
当然,这个答案假设事先知道行数和列数。如果您事先没有此信息,则计算行数总是需要一段时间,因为您必须读取整个文件并计算字符数\n
。像这样的东西就足够了:
num_rows = 0
for line in open("data/training_nohead.csv")
num_rows += 1
Run Code Online (Sandbox Code Playgroud)
对于列数,如果每行都有相同的列数,那么您可以只计算第一行,否则您需要跟踪最大值。
num_rows = 0
max_cols = 0
for line in open("data/training_nohead.csv")
num_rows += 1
tmp = line.split(",")
if len(tmp) > max_cols:
max_cols = len(tmp)
Run Code Online (Sandbox Code Playgroud)
该解决方案最适合数字数据,因为包含逗号的字符串确实会使事情变得复杂。