2010-11-26 27 views
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}}, ...} 

私はインポート機能でそれを行う方法を見つけることができませんでした。私は

myProcessingFunctionは、一度に1つのレコードを取得し、データセットを作成します
Import["my_file.csv", "CSV", myProcessingFunction] 

のようなものを探しています。 Importやその他のMathematica関数でこれを行うことは可能ですか?

+0

わからない場合は、これをランレングスエンコーディングといいます。 Mathematicaアルゴリズムを実装するためのいくつかのきちんとしたアルゴリズムがあります。 –

+2

@Tim Kemp:アルゴリズムを実行する前に、まずデータをロードする必要があります。データのサイズでは、データを一度に読み込むことはできません。私の質問は、レコードをグループ化する方法ではなく、行ごとにデータをロードする方法です。また、RLEアルゴリズムはレコードのシーケンスを保存します。私はこれを必要としません。私は数だけ必要です。例えば、RLEが3A、4B、4Aになった後のAAABBBBAAAA。私は7A、4Bが必要です。 – Max

答えて

2

もし私だったら、私はおそらくUNIXのsortuniqを使ってこれを行うでしょうが、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"]] 
+0

+1、間違いなく私が取る方法。三つのこと。 whileループは 'CheckAbort'でラップする必要があります。それ以外の場合、ストリームは開いたままになります。これは、大きなファイルを扱う際には不可欠です。第2に、セミコロンは 'WordSeparators'に含まれなければなりません。そうしないと、セミコロンはCSVファイルで多くのエラーを生成します。最後に、600 mbファイルでどのくらいうまく動作しますか? – rcollyer

+0

@rcollyer、CheckAbort処理を追加しました。この関数は行のみを処理します。メモリを節約するフィールドを分離しません。それは、 ";"で中断するReadListを変更するのと同じくらい簡単でなければなりません。 –

2

Read[]機能が必要だと思います。

2

おそらく、これを行うための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

もちろん、Mathematicaの中からawkやperlを呼び出すこともできます。 –

0

私は、MySQLなどのデータベースシステムに最初にそれをロードを検討することをお勧めいたしますでしょうし、あなたがのMathematica DatabaseLinkを使用してからアクセスすることができます。

関連する問題