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

我正在使用encoding/csv读取和解析一个非常大的 .csv 文件。

我需要随机选择行并通过一些测试。

我目前的解决方案是读取整个文件,如


reader := csv.NewReader(file)

lines, err := reader.ReadAll()

然后从lines

其中随机选择行明显的问题是阅读整个内容需要很长时间,而且我需要大量内存。


提问:

我的问题是,encoding/csv给我的io/reader是有没有用它来阅读,而不是一次加载整个事情乱行的方法吗?

这io/reader与其说是一个实际问题,不如说是一个需要了解更多的好奇心,因为很可能最终读取一次并在内存中访问它更有效,而不是继续在磁盘上寻找随机行。


森栏
浏览 400回答 3
3回答

慕尼黑5688855

Apokalyptik 的答案最接近你想要的。读者是流媒体,所以你不能只是跳到一个随机的地方(本身)。天真地选择在读入时保留任何给定行的概率可能会导致问题:您可能在没有保留足够输入行的情况下到达文件末尾,或者您可能太快地保留行而没有得到很好的样本。两者都比正确猜测更有可能,因为您事先不知道文件中有多少行(除非您先迭代一次以计算它们)。您真正需要的是水库取样。基本上,逐行读取文件。每一行,你都可以这样选择是否持有:你阅读的第一行,你就有1/1机会持有。阅读第二行后,您有1/2机会用这一行替换您持有的内容。在第三行之后,您有1/2 * 2/3 = 1/3机会抓住那一行。因此,你有1/N机会抓住任何给定的行,N你读入的行数在哪里。 这里有一个更详细的算法(不要试图仅仅根据我在这篇文章中告诉你的内容来实现它单独段落)。

收到一只叮咚

最简单的解决方案是在阅读每一行时做出决定,是测试它还是丢弃它......让你的决定随机化,这样你就不需要将整个东西保存在 RAM 中......然后通过运行测试后通过文件...您也可以使用非随机分布测试(例如在 X 字节或 X 行等之后)执行相同的样式
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go