2016-12-09 3 views
0

私はPython 2.7で読む必要があるファイルのコレクション(1〜10GBのファイルが複数のファイルに分割されているので、〜1GB程度です)があります。ファイル形式は、このようなものです:Python 2.7で2つの異なる行形式の大きなCSVファイルをメモリ制約で解析しますか?

1|KEY1|A |B  |01/01/2016| | 
2|KEY1| |LINEINDEX1|C   |D |E     | 123.000| 456.000| 789.1250|000100000.00|000100000.70|100|01/2016| 001|100|01/2016|050|050|01|001|100|F |G   |H |1|I|J | |K |L |M |  | | |  |  | | | |  | |  | | |  |  |  |  | |    | |  |       | |    |   | |    | | | | |  |  |  | | | | |    |  |    | |  |  | | | | |  |   | | 
2|KEY1| |LINEINDEX2|C   |D |E     | 123.000| 456.000| 789.1250|000100000.00|000100000.70|100|01/2016| 001|100|01/2016|050|050|01|001|100|F |G   |H |1|I|J | |K |L |M |  | | |  |  | | | |  | |  | | |  |  |  |  | |    | |  |       | |    |   | |    | | | | |  |  |  | | | | |    |  |    | |  |  | | | | |  |   | 
2|KEY1| |LINEINDEX3|C   |D |E     | 123.000| 456.000| 789.1250|000100000.00|000100000.70|100|01/2016| 001|100|01/2016|050|050|01|001|100|F |G   |H |1|I|J | |K |L |M |  | | |  |  | | | |  | |  | | |  |  |  |  | |    | |  |       | |    |   | |    | | | | |  |  |  | | | | |    |  |    | |  |  | | | | |  |   | | 
2|KEY1| |LINEINDEX4|C   |D |E     | 123.000| 456.000| 789.1250|000100000.00|000100000.70|100|01/2016| 001|100|01/2016|050|050|01|001|100|F |G   |H |1|I|J | |K |L |M |  | | |  |  | | | |  | |  | | |  |  |  |  | |    | |  |       | |    |   | |    | | | | |  |  |  | | | | |    |  |    | |  |  | | | | |  |   | |  
1|KEY2|A |B  |01/01/2016| | 
2|KEY2| |LINEINDEX5|C   |D |E     | 123.000| 456.000| 789.1250|000100000.00|000100000.70|100|01/2016| 001|100|01/2016|050|050|01|001|100|F |G   |H |1|I|J | |K |L |M |  | | |  |  | | | |  | |  | | |  |  |  |1  | |    | |  |       | |    |   | |    | | | | |  |  |  | | | | |    |N  |    | |  |  | | | | |  |   | |  
2|KEY2| |LINEINDEX6|C   |D |E     | 123.000| 456.000| 789.1250|000100000.00|000100000.70|100|01/2016| 001|100|01/2016|050|050|01|001|100|F |G   |H |1|I|J | |K |L |M |  | | |  |  | | | |  | |  | | |  |  |  |4  | |    | |  |       | |    |   | |    | | | | |  |  |  | | | | |    |O  |    | |  |  | | | | |  |   | | 

ユニークLINEINDEX#値を無限に繰り返すことができ、その後、次の行は、独自のライン2続く新しいKEY項目(のため1で始まります2で始まる行、等々)。私は効率的に複数のKEYに基づいて2データ型のテーブルを生成する必要があるので、私は実際には1の行を必要としません。空のフィールドにはデータがあるかもしれないし、そうでないかもしれないので、そこにあるすべてのものをキャプチャする必要がある。

このデータを取り囲むプログラムのほとんどはパンダを使用しているので、私は理想的にそれに固執しようとしていました。私の計画は、これらのファイルをHDF5ファイルに解析し、必要に応じてそのファイルからテーブルを作成することでした。私はそれが手元の問題に対処する最善の方法であるかどうか分からないので、代替案の提案は歓迎されます。現在、この処理はffdf経由でRで行われますが、Pythonに移動する必要があります。

私はこれらのファイルを1行ずつ読むことができません(メモリが不足してすぐにポップアップします)。1という行を削除/無視できません。私はPandas read_csvcomment='1'を試して、これらの行を "コメント"として扱い無視しましたが、CParserErrorを取得しました。これは他の投稿に基づいたものよりもバグが多いようです(最初の行をスキップしましたそのエラーは、トリックをしなかった)。

to_hdf、同様のパフォーマンスの問題を変換する際に、次に

sys:1: DtypeWarning: Columns (21) have mixed types. Specify dtype option on import or set low_memory=False. 

:私は(私が持っている)データ型を指定せずにファイルを処理した場合、私はパフォーマンスの問題、例えばを得る

pandas.io.common.CParserError: Error tokenizing data. C error: Expected 4 fields in line 504, saw 14 

C:\Python27\lib\site-packages\pandas\core\generic.py:1138: PerformanceWarning: 
your performance may suffer as PyTables will pickle object types that it cannot map directly to c-types 

1で始まる行をすべて無視するか、ouを実行しないで2つの異なるdTypeマップを何らかの方法で指定する最良の方法は何ですか。私は行単位で作業しようとするたびに発生します。このデータをKEYのリストに基づいて2の広告申込情報を照会するためのより良い方法がありますか?

は今のところ、コードは単純です:

for input_file in os.listdir(input_path): 
      file_path = input_path + '\\' + input_file 
      data = pd.read_csv(file_path, sep='|') 
      data.to_hdf(self.outputs_path + '\converted.h5', 'converted_table') 
+0

入力データのサンプルを長く投稿する必要があります。入力データのサンプルを投稿する必要があります。テキストの説明だけで意味のある方法でアドバイスすることができます。 (テキスト "LINEINDEX"は変更されるか固定されていますか? "KEY"は各行でテキストに繰り返されますか?非 "1"行の "KEY"の後に、あなたの望みの識別子が入っていますか? – jsbueno

+0

これらのファイルをクリーンアップして、データフレームワークをロードし、うまく動作するCSVファイルを作成することをお勧めします。これは、処理ニーズに応じて2回目のパスで使用できます。 – jsbueno

+0

これまでに行った試行のコードを投稿してください。 – James

答えて

0

これはスペースを入れずに、パイプ間の任意のデータを抽出し、新しいファイルにその情報をダンプします。文字列'LINEINDEX'を含む行のみを書き出し、パイプ間の値がすべて空白の場合は無視されます。パイプ間に空の値を保持する必要がある場合は、リストの理解からif節(if x.replace(' ',''))を削除します。

with open('/path/to/in_file.csv', 'r') as fp: 
    with open('/path/to/out_file.csv', 'w') as fp2: 
     for line in fp: 
      if 'LINEINDEX' in line: 
       out = [x.replace(' ','') for x in line.strip().split('|') 
         if x.replace(' ','')] 
       fp2.write(','.join(out)+'\n') 

ファイル全体がメモリに読み込まれるのではなく、一度に1つずつ読み書きされるため、メモリに問題はありません。

関連する問題