我正在使用encoding/csv
读取和解析很大的.csv文件。
我需要随机选择线并通过一些测试。
我当前的解决方案是读取整个文件
reader := csv.NewReader(file)
lines, err := reader.ReadAll()
然后从随机选择行lines
。明显的问题是读取整个内容需要很长时间,并且我需要大量内存。
提问:
我的问题是,encoding/csv
给我的io/reader
是有没有用它来阅读,而不是一次加载整个事情乱行的方法吗?与实际问题相比,
这更多地是要学习io/reader
,因为最终很有可能读取一次并访问它在内存中效率更高,从而可以在磁盘上不断寻找随机行。
Apokalyptik的答案是最接近您想要的答案。读者是流光,因此您不能随便跳到一个随机的地方。
天真地选择在阅读时保留给定行的概率可能会导致问题:您可能会在没有足够输入行的情况下到达文件末尾,或者您可能太快而无法保持行并没有得到好样本。这两种方法都比正确猜想更有可能,因为您事先不知道文件中有多少行(除非您先对其进行一次迭代以对其进行计数)。
您真正需要的是储层采样。
基本上,逐行读取文件。在每一行中,您都可以选择是否像这样保留它:在阅读的第一行中,您有1/1
机会保留它。阅读完第二行后,您就有1/2
机会用这一行替换您持有的内容。在第三行之后,您有1/2 * 2/3 = 1/3
机会坚持住这一行。因此,您有1/N
机会抓住任何给定的行,N
即已读入的行数是多少。这里是对该算法的更详细介绍(不要仅仅根据我在本文中告诉您的内容来实现该算法仅此段)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句