Import 大文本文件处理

Import 大文本文件处理,import,wolfram-mathematica,text-processing,Import,Wolfram Mathematica,Text Processing,我需要在Mathematica中实现延迟加载。我有一个600 Mb的CSV文本文件,我需要处理。此文件包含大量重复记录: 1;0;0;13;6 1;0;0;13;6 .......... 2;0;0;13;6 2;0;0;13;6 .......... etc. 因此,我不想将它们全部加载到内存中,而是想创建一个列表,其中包含记录以及文件中遇到该记录的次数: {{10000,{1,0,0,13,6}}, {20000,{2,0,0,13,6}}, ...} 我找不到使用导入功能的方法。我在找

我需要在Mathematica中实现延迟加载。我有一个600 Mb的CSV文本文件,我需要处理。此文件包含大量重复记录:

1;0;0;13;6
1;0;0;13;6
..........
2;0;0;13;6
2;0;0;13;6
..........
etc.
因此,我不想将它们全部加载到内存中,而是想创建一个列表,其中包含记录以及文件中遇到该记录的次数:

{{10000,{1,0,0,13,6}}, {20000,{2,0,0,13,6}}, ...}
我找不到使用导入功能的方法。我在找像这样的东西

Import["my_file.csv", "CSV", myProcessingFunction]

其中myProcessingFunction将一次获取一条记录并创建一个数据集。是否可以使用Import或任何其他Mathematica函数执行此操作?

我认为您需要
Read[]
函数。

也许有比Mathematica更好的替代方法来执行此操作

一个小的awk脚本:

 {a[$0]++}  
 END { ... print loop ... }
将累积重复记录。当然,根据不同记录的数量,您可能会遇到溢出

或者先对文件进行排序,计数不会溢出。在awk中,非溢出程序可能类似于

 BEGIN{ p =""; i=0}

 {if (($0 != p) &&  (i != 0) ) {print $0,i ; p =$0; i=0; next}}

 {i++; p = $0}  
也许Perl更好,但我已经过时了


如果是我,我可能会使用unix
sort
uniq
来实现这一点,但既然你问起Mathematica。。。。我将使用ReadList[]读取行块,并定义downValue以查找唯一的字符串,从而跟踪我们以前见过的字符串数量

(* Create some test data *)
Export["/tmp/test.txt", Flatten[{Range[1000], Range[1000]}], "Lines"];

countUniqueLines[file_String, blockSize_Integer] := Module[{stream, map, block, keys, out}, 
    map[_]:=0;
    stream = OpenRead[file];
    CheckAbort[While[(block=ReadList[stream, String, blockSize])=!={}, 
        (map[#]=map[#]+1)& /@ block;];, Close[stream];Clear[map]];
    Close[stream];
    keys = Cases[DownValues[map][[All, 1, 1, 1]], _String];
    out = {#, map[#]}& /@ keys;
    Clear[map];
    out
]

countUniqueLines["/tmp/test.txt", 500]


(* Alternative implementation if you have a little more memory *)
Tally[Import["/tmp/test.txt", "Lines"]]

<>我建议你先把它装入一个像MySQL这样的数据库系统,然后你可以使用Mathematica使用DavaSelink来访问它。

当然可以在Mathematica中调用AWK或Perl。如果你不知道,这叫做游程长度编码。有几种简洁的Mathematica算法可以实现它。@Tim Kemp:在运行算法之前,我需要先加载数据。数据的大小不允许立即加载。我的问题是如何逐行加载数据,而不是如何对记录进行分组。此外,RLE算法保留记录序列。我不需要这个。我只需要计数。例如,RLE变为3A、4B、4A后的AAABBAAAA。我需要7A,4B.+1,绝对是我会采取的方法。三件事。while循环需要被包装在一个
CheckAbort
中,否则当调用时流将保持打开状态。这在处理大文件时非常重要。其次,分号必须包含在
字分隔符中,否则它将在CSV文件中生成大量错误。最后,它在600 mb文件中的表现如何?@rcollyer,我添加了CheckAbort处理。此函数仅处理行;它不分隔字段,从而节省了一些内存。不过,它应该像将ReadList更改为“打开”一样简单。