我正在尝试选择要从CSV文件中读取的行,选择基于:
n = 123456789
s = n//10
# skip value will be used with skip_row in pd.read_csv
skip = sorted(random.sample(range(1, n+1), k=(n-s))
由于RAM使用率过高,此行导致脚本崩溃。文件大小接近5 GB,这就是为什么需要随机读取10%的文件。 期望是random.select不会占用太多内存,令人惊讶的是它(最多可达5 GB,甚至更多,如任务管理器所示)
是否有一种有效的方法来选择要跳过的行。
答案 0 :(得分:0)
感谢所有评论,我设法编写了一个代码,在31秒内找到所有n = 123456789标签/样本(使用Core i5 PC),这里是:
import random
import time
start_time = time.time()
n=123456789
if n>123456789:
step_size = int(1e7)
else:
step_size=n//10
no_of_steps = n//step_size-1
s= step_size//10
xx=list(); i=0
while (i<no_of_steps):
xx= xx + sorted(random.sample(range(i*step_size, (i+1)*step_size-1), k= s))
i +=1
print("Size of selected samples", len(xx))
print("Percentage achieved", len(xx)/n)
print("Time needed to pick 10% from ", n, "samples is:" , time.time()-start_time)
print("-------- \n Show a few samples", xx[:10], '...', xx[-10:])
答案 1 :(得分:-1)
的确,你目前的方法很重。它真的试图在内存中存储和处理(sample + sort)一个123,456,789个python整数数组。我不相信你实际上需要事先在数组中“跳过”行。如果是这样,您可以使用generator
。以下是您可以改为generating
样本集的方法:
def random_sampler_generator(input_seq, skip_chance=0.5):
for i in input_seq:
if random.random() > skip_chance:
yield i
for m in random_sampler_generator(xrange(1, n+1), skip_chance=0.1):
print m
这有点慢,因为它调用random.random()超过1亿次,但由于yield
函数,它的内存效率非常高。出于同样的原因,您可能也应该使用xrange
代替range
。
在这里,random_sampler_generator
使用启发式抽样方法,因为您不能保证X%
,但随着输入集大小的增加,结果会倾向于它。 skip_chance
期望浮点数介于0和1之间,其中.1跳过10%,.5跳过50%,.75跳过75%等等。
答案 2 :(得分:-1)
您需要数据的随机子集,但是您抱怨数据太大而无法驻留内存。因此,使用外部排序可以使您的数据达到合适的形状。
从source.csv
读取所有N个记录,在计数器的PRNG或SHA1之前添加一个随机值,或者(对于唯一记录)每个记录的SHA1,并将N个结果记录发送到{{1或关系数据库中的索引表。
现在您的记录以随机顺序显示在磁盘上,您可以通过读取前S条记录轻松执行第一个实验,而不会影响内存。记住你离开的地方,你可以通过阅读下一个S记录来进行第二次实验。或者,另一种方法是询问第一个S记录,其中初始SHA1 nybble为'3',另一个S记录以'5'开头,依此类推。您的实验设计不必担心在多个实验中随机遇到相同的源记录,因为您创建了非重叠的分区。
编辑:无需替换生成随机索引不同于生成实验数据的随机折叠。请求是为了节省内存。这种方法工作速度很快,内存有限(永远不会与/usr/bin/sort
成比例),使用CSV输入指定的OP问题。尾部-4给出了结果,在OP所需的数据大小的前置运行在五分钟(302秒),这种运行大约一分钟(77秒):
s