当前位置: 首页 > 知识库问答 >
问题:

分析CSV时发生OutOfMemoryError

鲁龙野
2023-03-14

我有一个巨大的csv文件(500MB)和400k条记录

id, name, comment, text
1, Alex, Hello, I believe in you

栏目文本由许多信息和句子组成。我想获取此列(“文本”),将所有非字母符号替换为“”,并将其按从“文本”列中最常见的单词到最不常见的单词(限制为1000)的相反顺序排序。这就是它的样子。我正在使用CsvReader库

CsvReader doc = new CsvReader("My CSV Name");
        doc.readHeaders();
        try {
            List<String> listWords = new ArrayList<>();
            while (doc.readRecord()) {
                listWords.addAll(Arrays.asList(doc.get("Text"/*my column name*/).replaceAll("\\P{Alpha}", " ").toLowerCase().trim().split("[ ]+")));
            }

            Map<String, Long> sortedText = listWords.stream()
                    .collect(groupingBy(chr -> chr, counting()))
                    .entrySet().stream()
                    .sorted(Map.Entry.comparingByValue(Collections.reverseOrder()))
                    .limit(1000)
                    .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            Map.Entry::getValue,
                            (e1, e2) -> e1,
                            LinkedHashMap::new
                    ));
            sortedText.forEach((k, v) -> System.out.println("Word: " + k + " || " + "Count: " + v));
            doc.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            doc.close();
        }

运行后,我出现内存不足错误,GC超过了该错误。如何做到最好?我不能增加堆大小,我只需要使用默认设置

共有1个答案

徐鸿达
2023-03-14

针对该问题的建议是:不要在列表中添加所有单词,而是尝试按处理的每个CSV行计算单词。

代码如下:

CsvReader doc = null;

try {

    doc = new CsvReader(""My CSV Name");
    doc.readHeaders();

    Map<String, Long> mostFrequent = new HashMap<String, Long>();

    while (doc.readRecord()) {

        Arrays.asList(doc.get("text"/*my column name*/).replaceAll("\\P{Alpha}", " ").toLowerCase().trim().split("[ ]+")).
        stream().forEach(word -> {

            if (mostFrequent.containsKey(word)) {
                mostFrequent.put(word, mostFrequent.get(word) + 1);  
            }
            else {
                mostFrequent.put(word, 1l);
            }
        });
    }

    Map<String, Long> sortedText = mostFrequent.entrySet().stream()
        .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
        .limit(1000)
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                (e1, e2) -> e1, LinkedHashMap::new));

    sortedText.forEach((k, v) -> System.out.println("Word: " + k + " || " + "Count: " + v));

    doc.close();

} catch (IOException e) {
    e.printStackTrace();
} finally {
    doc.close();
}
 类似资料:
  • 实际上,这个问题与我之前的问题有关,即在Java和ANTLRWorks调试器中捕获ANTLR的NoViableAltExcema,但由于症状不同,我决定将它们分开。 问题在于如何将输入文本馈送到ANTLR,其中包含未知标记。例如,我们的语法不知道什么是令牌,它从<代码> @ <代码>符号开始。如果我们试图将此类文本提供给解释器,我们将在结果图中收到。 但是,如果我们使用Java生成和编译的语法并尝

  • 在读取“100 MB”的大型XML文件并使用xstream对其进行解析时,我遇到了一个问题始终会出现以下错误 下面是解析XML的代码 ClassName是一个普通类,其字段带有xml注释。 然后使用 fileString:将xml文件作为inputstream读取并放入字符串缓冲区后的xml文件。 以上代码适用于小文件,但不适用于大文件,有什么想法吗?

  • 本文向大家介绍C# 解析 Excel 并且生成 Csv 文件代码分析,包括了C# 解析 Excel 并且生成 Csv 文件代码分析的使用技巧和注意事项,需要的朋友参考一下 今天工作中遇到一个需求,就是获取 excel 里面的内容,并且把 excel 另存为 csv,因为本人以前未接触过,所以下面整理出来的代码均来自网络,具体参考链接已丢失,原作者保留所有权利! 例子: ExcelUtils.cs

  • 我正在尝试使用opennlp处理文档分类器。但是我对训练文件有困难。当opennlp读取文件时,我收到以下错误: 我的培训文件如下所示: 我没有得到我可能错过的东西。

  • 问题内容: 我正在使用以下时间戳格式: 以下方法可以正常工作: 而且,当我使用该格式字符串传递时间戳时,它返回,例如: 然后,我需要再次从该字符串映射到时间戳,本质上是相反的操作。我知道我可以使用和及其方法,但是如果可能的话,我宁愿坚持使用样式格式。 我写了这段代码(相当hacky),它适用于某些格式,但不适用于特定格式: 在第二部分,它失败了。 堆栈跟踪: 有没有一种更简单的方法可以在不利用我的

  • 我使用数据库领域,我有一个json对象,我需要从文件中解析并保存到数据库。 问题出现在对象pCommercialAccessRulle中,其中有一个字符串列表,不支持基本类型,这就是我创建对象的原因。 在类商业访问规则中,我创建的不是字符串列表,而是对象RealmString列表 但我犯了这样一个错误 搜索之后,我去了那里,然后又去了那里,但不知道如何在这里实现它: 这是我上面写的类PDate,