web-dev-qa-db-ja.com

pandas.HDFStoreテーブルから列を選択する

pandas HDFStoreから特定の列を取得するにはどうすればよいですか?メモリ内で操作するには大きすぎる非常に大きなデータセットを定期的に処理します。csvファイルを繰り返し読み取り、それぞれを追加しますHDFStoreオブジェクトにチャンクしてから、データのサブセットを操作します。単純なcsvファイルを読み込んで、次のコードを使用してHDFStoreにロードしました。

_tmp = pd.HDFStore('test.h5')
chunker = pd.read_csv('cars.csv', iterator=True, chunksize=10, names=['make','model','drop'])
tmp.append('df', pd.concat([chunk for chunk in chunker], ignore_index=True))
_

そして出力:

_In [97]: tmp
Out[97]:
<class 'pandas.io.pytables.HDFStore'>
File path: test.h5
/df     frame_table (typ->appendable,nrows->1930,indexers->[index])
_

私の質問は、_tmp['df']_から特定の列にアクセスするにはどうすればよいですか?このドキュメントでは、select()メソッドといくつかのTermオブジェクトについて言及しています。提供されている例は、パネルデータに適用されます。ただし、私は初心者であり、より単純なデータフレームの場合に拡張することはできません。私の推測では、どういうわけか列のインデックスを作成する必要があります。ありがとう!

18
Zelazny7

HDFStoreがテーブルを記録する方法では、列はタイプごとに単一のnumpy配列として格納されます。常にすべての列を取得し、それらをフィルタリングできるため、要求した内容が返されます。 0.10.0では、列を含む用語を渡すことができます。

store.select('df', [ Term('index', '>', Timestamp('20010105')), 
                     Term('columns', '=', ['A','B']) ])

または、後でインデックスを再作成できます

df = store.select('df', [ Term('index', '>', Timestamp('20010105') ])
df.reindex(columns = ['A','B'])

axesは、ここでは実際には解決策ではありません(実際に作成したのは、実際には転置されたフレームを格納することでした)。このパラメーターを使用すると、軸のストレージを並べ替えて、さまざまな方法でデータの位置合わせを行うことができます。データフレームの場合、それは実際にはあまり意味がありません。 3Dまたは4D構造の場合、ディスク上のデータアライメントは、非常に高速なクエリにとって非常に重要です。

0.10.1を使用すると、より洗練されたソリューション、つまりデータ列が可能になります。つまり、テーブルストアに独自の列として表される特定の列を選択できるため、実際にはそれらだけを選択できます。これが来ている味です。

 store.append('df', columns = ['A','B','C'])
 store.select('df', [ 'A > 0', Term('index', '>', Timestamp(2000105)) ])

これを行う別の方法は、ファイルの異なるノードに別々のテーブルを格納することです。その後、必要なものだけを選択できます。

一般的に、私は再び本当に広いテーブルをお勧めします。 haydenはPanelソリューションを提供します。これは、実際のデータ配置がデータのクエリ方法を反映している必要があるため、今のところメリットがあるかもしれません。

12
Jeff

次のように、列のインデックスを使用してデータフレームを格納できます。

import pandas as pd
import numpy as np
from pandas.io.pytables import Term

index = pd.date_range('1/1/2000', periods=8)
df = pd.DataFrame( np.random.randn(8,3), index=index, columns=list('ABC'))  

store = pd.HDFStore('mydata.h5')
store.append('df_cols', df, axes='columns')

次に、必要に応じて選択します。

In [8]: store.select('df_cols', [Term('columns', '=', 'A')])
Out[8]: 
2000-01-01    0.347644
2000-01-02    0.477167
2000-01-03    1.419741
2000-01-04    0.641400
2000-01-05   -1.313405
2000-01-06   -0.137357
2000-01-07   -1.208429
2000-01-08   -0.539854

どこ:

In [9]: df
Out[9]: 
                   A         B         C
2000-01-01  0.347644  0.895084 -1.457772
2000-01-02  0.477167  0.464013 -1.974695
2000-01-03  1.419741  0.470735 -0.309796
2000-01-04  0.641400  0.838864 -0.112582
2000-01-05 -1.313405 -0.678250 -0.306318
2000-01-06 -0.137357 -0.723145  0.982987
2000-01-07 -1.208429 -0.672240  1.331291
2000-01-08 -0.539854 -0.184864 -1.056217

DataFrameのインデックスを作成できるのは1つだけなので、これは理想的なソリューションではありません。心配なことに docs はあなたを示唆しているようですcan少なくともaxesを使用して、DataFrameに1つのインデックスを付けるだけです。

ディメンションのリストとともにaxesキーワードを渡します(現在、オブジェクトの合計ディメンションよりも正確に1少ない必要があります)。

私はこれを間違って読んでいる可能性があります、その場合誰かが私を間違っていると証明できることを願っています!

注:DataFrameに2つのインデックス(インデックスと列)でインデックスを付ける方法の1つは、パネルに変換することです。パネルは、2つのインデックスを使用して取得できます。ただし、アイテムが取得されるたびに、選択したサブパネルをDataFrameに変換する必要があります...これも理想的ではありません。

12
Andy Hayden

今後、UはTerm構文の代わりにクエリ式を使用できます。例:store.select('df', "index > Timestamp('20000105')")

0
Eagle Liang