python 使用 readline 采样给出内存错误
python sampling using readline gives memory error
我尝试对超过 2.6 亿行的数据文件进行采样,创建一个均匀分布的样本,样本大小固定为 1000 个。
我所做的是:
import random
file = "input.txt"
output = open("output.txt", "w+", encoding = "utf-8")
samples = random.sample(range(1, 264000000), 1000)
samples.sort(reverse=False)
with open(file, encoding = "utf-8") as fp:
line = fp.readline()
count = 0
while line:
if count in samples:
output.write(line)
samples.remove(count)
count += 1
line = fp.readline()
此代码导致内存错误,没有进一步说明。这段代码怎么会出现内存错误?
据我所知,它应该逐行读取我的文件。该文件有 28.4GB,因此不能作为一个整体读取,这就是我使用 readline() 方法的原因。我该如何解决这个问题,以便可以处理整个文件,无论其大小如何?\
编辑:
最近的尝试抛出了这个错误,这与我之前收到的每条错误消息几乎相同
MemoryError Traceback (most recent call last)
<ipython-input-1-a772dad1ea5a> in <module>()
12 with open(file, encoding = "utf-8") as fp:
13 count = 0
---> 14 for line in fp:
15 if count in samples:
16 output.write(line)
~\Anaconda3\lib\codecs.py in decode(self, input, final)
320 # decode input (taking the buffer into account)
321 data = self.buffer + input
--> 322 (result, consumed) = self._buffer_decode(data, self.errors, final)
323 # keep undecoded input until the next call
324 self.buffer = data[consumed:]
MemoryError:
所以看起来这一行会导致巨大的内存峰值:
samples = random.sample(range(1, 264000000), 1000)
我的猜测是,此调用会强制 python 创建该范围内的所有 264M 整数,然后才能进行采样。尝试使用此代码代替相同范围内的采样而不进行替换:
from random import randint
file = "input.txt"
output = open("output.txt", "w+", encoding = "utf-8")
samples = set()
while len(samples) < 1000:
random_num = randint(0, 264000000)
if random_num not in samples:
samples.add(random_num)
with open(file, encoding = "utf-8") as fp:
count = 0
for line in fp:
if count in samples:
output.write(line)
samples.remove(count)
count += 1
if not samples: break
已解决
我终于解决了这个问题:这里的所有代码都可以正常工作,
范围问题确实只存在于 3.0 之前的版本中,
它应该在哪里 xrange(1, 264000000).
输入文件是在不同的代码文件中构建的,
其中写法如下:
with open(file, encoding = "utf-8", errors = 'ignore') as fp:
line = fp.readline()
while line:
input_line = line.split(sep="\t")
output.write(input_line[1] + "," + input_line[2])
line = fp.readline()
这里的问题是这段代码并没有用行构造一个文件,而只是在第一行添加了信息。因此,整个文件被读取为一大行,而不是作为一个有很多行要迭代的文件。
非常感谢您的帮助,对于问题出在我项目的其他地方,我深表歉意。
我尝试对超过 2.6 亿行的数据文件进行采样,创建一个均匀分布的样本,样本大小固定为 1000 个。
我所做的是:
import random
file = "input.txt"
output = open("output.txt", "w+", encoding = "utf-8")
samples = random.sample(range(1, 264000000), 1000)
samples.sort(reverse=False)
with open(file, encoding = "utf-8") as fp:
line = fp.readline()
count = 0
while line:
if count in samples:
output.write(line)
samples.remove(count)
count += 1
line = fp.readline()
此代码导致内存错误,没有进一步说明。这段代码怎么会出现内存错误?
据我所知,它应该逐行读取我的文件。该文件有 28.4GB,因此不能作为一个整体读取,这就是我使用 readline() 方法的原因。我该如何解决这个问题,以便可以处理整个文件,无论其大小如何?\
编辑: 最近的尝试抛出了这个错误,这与我之前收到的每条错误消息几乎相同
MemoryError Traceback (most recent call last)
<ipython-input-1-a772dad1ea5a> in <module>()
12 with open(file, encoding = "utf-8") as fp:
13 count = 0
---> 14 for line in fp:
15 if count in samples:
16 output.write(line)
~\Anaconda3\lib\codecs.py in decode(self, input, final)
320 # decode input (taking the buffer into account)
321 data = self.buffer + input
--> 322 (result, consumed) = self._buffer_decode(data, self.errors, final)
323 # keep undecoded input until the next call
324 self.buffer = data[consumed:]
MemoryError:
所以看起来这一行会导致巨大的内存峰值:
samples = random.sample(range(1, 264000000), 1000)
我的猜测是,此调用会强制 python 创建该范围内的所有 264M 整数,然后才能进行采样。尝试使用此代码代替相同范围内的采样而不进行替换:
from random import randint
file = "input.txt"
output = open("output.txt", "w+", encoding = "utf-8")
samples = set()
while len(samples) < 1000:
random_num = randint(0, 264000000)
if random_num not in samples:
samples.add(random_num)
with open(file, encoding = "utf-8") as fp:
count = 0
for line in fp:
if count in samples:
output.write(line)
samples.remove(count)
count += 1
if not samples: break
已解决
我终于解决了这个问题:这里的所有代码都可以正常工作, 范围问题确实只存在于 3.0 之前的版本中, 它应该在哪里 xrange(1, 264000000).
输入文件是在不同的代码文件中构建的, 其中写法如下:
with open(file, encoding = "utf-8", errors = 'ignore') as fp:
line = fp.readline()
while line:
input_line = line.split(sep="\t")
output.write(input_line[1] + "," + input_line[2])
line = fp.readline()
这里的问题是这段代码并没有用行构造一个文件,而只是在第一行添加了信息。因此,整个文件被读取为一大行,而不是作为一个有很多行要迭代的文件。
非常感谢您的帮助,对于问题出在我项目的其他地方,我深表歉意。