代码之家  ›  专栏  ›  技术社区  ›  Max

大文本文件处理

  •  6
  • Max  · 技术社区  · 14 年前

    我需要在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函数来完成此操作?

    4 回复  |  直到 14 年前
        1
  •  2
  •   Joshua Martell    14 年前

    如果是我,我可能会用unix sort uniq ,但既然你问起Mathematica。。。。我将使用ReadList[]来读取行块,并定义downvalues来查找唯一的字符串,并跟踪我们以前看到的行数。

    (* 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"]]
    
        2
  •  2
  •   High Performance Mark    14 年前

    我想你想要 Read[] 功能。

        3
  •  2
  •   Dr. belisarius    14 年前

    也许有比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更好,但我是老式的。

    啊!

        4
  •  0
  •   gdelfino    14 年前

    我建议您首先考虑将它加载到MySQL这样的数据库系统中,然后您可以从 数学软件 使用数据库链接。