Обработка больших текстовых файлов - PullRequest
6 голосов
/ 26 ноября 2010

Мне нужно реализовать отложенную загрузку в Mathematica. У меня есть текстовый файл CSV 600 МБ, который мне нужно обработать. Этот файл содержит много повторяющихся записей:

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 ]

2 голосов
/ 26 ноября 2010

Возможно, есть и лучшие альтернативы, чем 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 лучше, но я старомоден.

HTH!

2 голосов
/ 27 ноября 2010

Если бы это был я, я, вероятно, сделал бы это, используя unix sort и uniq, но поскольку вы спрашиваете о Mathematica .... Я бы использовал ReadList [] для чтения блоков строк и определения значений вниз чтобы найти уникальные строки, следите за тем, сколько мы видели раньше.

(* 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 голосов
/ 26 ноября 2010

Я думаю, вы хотите функцию Read[].

0 голосов
/ 27 ноября 2010

Я бы порекомендовал вам сначала рассмотреть возможность его загрузки в систему базы данных, такую ​​как MySQL, а затем вы можете получить к ней доступ из Mathematica , используя DatabaseLink.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...