2017-05-29 3 views
1

計算を行うには、大きなファイル.txt(約10GB)をインポートする必要があります。私はPython 2.7でPandasを使用しています。Python&Pandas TextFileReaderオブジェクトの「チャンク」のサブセットを操作するにはどうすればよいですか?

基本的には、あるシリーズ(列)の合計と平均を、他のシリーズの値を条件として構築する必要があります。より正確には、私は国に住む個人に関する基本的な情報を持っています。たとえば、各自治体の平均年齢を取ることができます。

ファイルが大きすぎるため、ファイル全体をインポートできないため、「チャンク」(read_tablechunksizeを使用)で処理しています。 各計算では、チャンクのすべてが必要ではなく、その一部だけが必要です。

情報が順序付けされていない可能性があるので、最初にすべてのチャンクを繰り返して、どの地方自治体に情報があるかを識別します。したがって、各自治体について、少なくとも1つの所見を含むチャンクのインデックスを持つリストがあります。

私は、このリストを使用してそれらのチャンクだけを選択したいと思いますが、私は早くそれを行うことができません。 動作しているように見えるのは、すべてのチャンクを繰り返し処理することだけです。

TextFileReaderオブジェクトで「チャンク」のサブセットを直接選択する方法はありますか?すべてを繰り返す必要はありませんか?

答えて

0

私は、このようにそれを行うにしようとするだろう:

res = \ 
pd.concat([df.assign(age=(pd.datetime.now() - df.dob).astype('m8[Y]').astype(int)) 
      .groupby(['country','municipality'])['age'].agg(['size','sum']).reset_index() 
      for df in pd.read_csv('/path/to/file.txt', sep=..., chunksize=10**5) ], 
      ignore_index=True) 

res = res.groupby(['country','municipality'], as_index=False).sum() 

これはあなたに、各自治体(size列)内の個人の合計数と年齢の合計(sum列)を提供します。

sum/size -

UPDATEあなたの自治体あたりの平均年齢を与える:あなたがその場で年齢を計算するために、次のトリックを使用することができます。

In [164]: df 
Out[164]: 
    country municipality  dob 
0 Ukraine   m1 1950-01-01 
1 Ukraine   m1 1960-12-14 
2  USA   m2 1971-11-27 
3  USA   m2 1982-11-09 
4  USA   m3 1993-10-22 
5 Germany   m1 2004-10-04 
6 Germany   m2 2015-09-17 

In [165]: df.assign(age=(pd.datetime.now() - df.dob).astype('m8[Y]').astype(int)) 
Out[165]: 
    country municipality  dob age 
0 Ukraine   m1 1950-01-01 67 
1 Ukraine   m1 1960-12-14 56 
2  USA   m2 1971-11-27 45 
3  USA   m2 1982-11-09 34 
4  USA   m3 1993-10-22 23 
5 Germany   m1 2004-10-04 12 
6 Germany   m2 2015-09-17 1 

にアップデート2:pd.read_csv()chunksizeを指定するとすぐにDataFrameの代わりにpandas.io.parsers.TextFileReaderを返します。

In [6]: reader = pd.read_csv(r'D:\temp\.data\1.csv', chunksize=3, sep='\s+') 

In [7]: type(reader) 
Out[7]: pandas.io.parsers.TextFileReader 

は2行

In [12]: reader.get_chunk(2) 
Out[12]: 
     foo foo.1 bar bar.1 spam spam.1 
foo 0.00 0.35 0.83 0.84 0.90 0.89 
foo 0.35 0.00 0.86 0.85 0.92 0.91 

は、次の3行

In [13]: reader.get_chunk(3) 
Out[13]: 
     foo foo.1 bar bar.1 spam spam.1 
bar 0.83 0.86 0.00 0.25 0.88 0.87 
bar 0.84 0.85 0.25 0.00 0.82 0.86 
spam 0.90 0.92 0.88 0.82 0.00 0.50 
+0

をゲットあなたの答えのために非常に多くの@MaxUありがとうございます。私はこれが私が質問で与えた具体例のために働くと信じています。しかし、計算を行う前にデータを処理しなければならない場合があり、すべてのチャンクに対して毎回反復処理を避けることができるかどうかを知りたい場合があります。特に、[年齢]列を持つ代わりに['date_of_birth']列があると、コードをどのように変更しますか?再度、感謝します! – Vincent

+0

ありがとう@MaxU。特定のチャンクを「選択」することが可能かどうかはまだ分かりませんが、ソリューションは良好であり、実行する必要はありません。あなたが知っている場合は、 'TextFileReader'オブジェクトの使い方が欲しいです。なぜなら、私はそれが何であり、どのように動作するのかを明確に知ることができないからです。 – Vincent

+0

@Vincent、更新された回答を確認してください – MaxU

関連する問題