在go中读取文本文件中的随机行

但:

我正在使用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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章