2013-11-28 6 views
5

Aby zarządzać ilością pamięci RAM, którą zużyję podczas analizy, mam duży zbiór danych przechowywany w formacie hdf5 (.h5) i muszę wydajnie wypytywać ten zestaw danych, używając Pand.Jak wysłać zapytanie do sklepu HDF za pomocą Pandy/Python

Zestaw danych zawiera dane o wydajności użytkowników dla zestawu aplikacji. Chcę tylko wyciągnąć kilka pól z 40 możliwych, a następnie przefiltrować wynikową ramkę danych tylko do tych użytkowników, którzy korzystają z jednej z niewielu interesujących mnie aplikacji.

# list of apps I want to analyze 
apps = ['a','d','f'] 

# Users.h5 contains only one field_table called 'df' 
store = pd.HDFStore('Users.h5') 

# the following query works fine 
df = store.select('df',columns=['account','metric1','metric2'],where=['Month==10','IsMessager==1']) 

# the following pseudo-query fails 
df = store.select('df',columns=['account','metric1','metric2'],where=['Month==10','IsMessager==1', 'app in apps']) 

Rozumiem, że ciąg "aplikacja w aplikacjach" nie jest tym, czego chcę. Jest to po prostu podobna do SQL prezentacja tego, co mam nadzieję osiągnąć. Nie mogę przekazać listy strun w jakikolwiek sposób, który próbuję, ale musi być jakiś sposób.

Na razie jestem po prostu uruchamiając zapytanie bez tego parametru, a potem odfiltrować aplikacje nie chcę w kolejnym etapie thusly

df = df[df['app'].isin(apps)] 

Ale to jest dużo mniej wydajny, ponieważ wszystkie aplikacje najpierw trzeba je załadować do pamięci, zanim będę mógł je usunąć. W niektórych przypadkach jest to duży problem, ponieważ nie mam wystarczającej ilości pamięci, aby obsłużyć cały niefiltrowany plik df.

Doceniam pomoc. To jest moje pierwsze pytanie dotyczące StackOverflow, więc wszelkie rady są mile widziane.

Odpowiedz

13

Jesteś całkiem blisko.

In [1]: df = DataFrame({'A' : ['foo','foo','bar','bar','baz'], 
         'B' : [1,2,1,2,1], 
         'C' : np.random.randn(5) }) 

In [2]: df 
Out[2]: 
    A B   C 
0 foo 1 -0.909708 
1 foo 2 1.321838 
2 bar 1 0.368994 
3 bar 2 -0.058657 
4 baz 1 -1.159151 

[5 rows x 3 columns] 

Napisz sklep jako tabelę (zauważ, że w 0,12 użyjesz table=True zamiast format='table'). Pamiętaj, aby podać data_columns który chcesz zapytać podczas tworzenia tabeli (lub można zrobić data_columns=True)

In [3]: df.to_hdf('test.h5','df',mode='w',format='table',data_columns=['A','B']) 

In [4]: pd.read_hdf('test.h5','df') 
Out[4]: 
    A B   C 
0 foo 1 -0.909708 
1 foo 2 1.321838 
2 bar 1 0.368994 
3 bar 2 -0.058657 
4 baz 1 -1.159151 

[5 rows x 3 columns] 

składni w master/0.13, ISIN odbywa się poprzez query_column=list_of_values. Jest to prezentowane jako ciąg do miejsca.

In [8]: pd.read_hdf('test.h5','df',where='A=["foo","bar"] & B=1') 
Out[8]: 
    A B   C 
0 foo 1 -0.909708 
2 bar 1 0.368994 

[2 rows x 3 columns] 

Składnia w 0.12, musi to być lista (która i warunki).

In [11]: pd.read_hdf('test.h5','df',where=[pd.Term('A','=',["foo","bar"]),'B=1']) 
Out[11]: 
    A B   C 
0 foo 1 -0.909708 
2 bar 1 0.368994 

[2 rows x 3 columns] 
+0

Dzięki @Jeff. To działało świetnie –