2013-07-15 3 views
5

Pandas에서는 테이블 형식으로 HDFStore에있는 모든 MultiIndex 색인을 효율적으로 가져올 수 있습니까?MultiIndex DataFrames의 Pandas HDFStore : 효율적으로 모든 색인을 얻는 방법

나는 where=을 사용하여 효율적으로 select()을 사용할 수 있지만 모든 색인과 모든 열을 원합니다. 또한 select()을 사용하면 RAM을 절약하기 위해 iterator=True을 사용할 수 있지만 여전히 디스크에서 모든 테이블을 읽는 것을 의미하므로 여전히 느립니다.

나는 store.root..table. * 물건에서 사냥을 해왔다. 색인 값 목록을 얻을 수 있기를 바란다. 나는 올바른 길을 가고 있는가?

플랜 B는 주 데이터를 추가 할 때마다 추가 된 빈 DataFrames를 포함하는 짧은 MultiIndex DataFrame을 유지하는 것입니다. 나는 그것을 찾아서 색인보다 훨씬 더 싸게 얻을 수 있습니다. 우아하지.

답변

5

DF 다중 색인을 생성

In [44]: store.get_storer('df').levels 
Out[44]: ['one', 'two'] 

In [2]: store 
Out[2]: 
<class 'pandas.io.pytables.HDFStore'> 
File path: test.h5 
/df   frame_table (typ->appendable_multi,nrows->100000,ncols->5,indexers->[index],dc->[two,one]) 

를 저장된 객체를 반환 (그러나 데이터를 검색하지) 않습니다 테이블

In [42]: store = pd.HDFStore('test.h5',mode='w') 

In [43]: store.append('df',mi) 

get_storer

In [35]: df = DataFrame(randn(100000,3),columns=list('ABC')) 

In [36]: df['one'] = 'foo' 

In [37]: df['two'] = 'bar' 

In [38]: df.ix[50000:,'two'] = 'bah' 

In [40]: mi = df.set_index(['one','two']) 

In [41]: mi 
Out[41]: 
<class 'pandas.core.frame.DataFrame'> 
MultiIndex: 100000 entries, (foo, bar) to (foo, bah) 
Data columns (total 3 columns): 
A 100000 non-null values 
B 100000 non-null values 
C 100000 non-null values 
dtypes: float64(3) 

스토어를 인덱스 수준은 data_columns로 생성되므로 선택 항목에서 사용할 수 있습니다. 이것은 하나의 열을 선택하고도 될 수있는 (

In [49]: store.select('df',columns=['A']) 
Out[49]: 
<class 'pandas.core.frame.DataFrame'> 
MultiIndex: 100000 entries, (foo, bar) to (foo, bah) 
Data columns (total 1 columns): 
A 100000 non-null values 
dtypes: float64(1) 

이 시리즈로 하나의 열을 선택하려면 마일 프레임으로 돌아가려면 인덱스 만

In [48]: store.select('df',columns=['one']) 
Out[48]: 
<class 'pandas.core.frame.DataFrame'> 
MultiIndex: 100000 entries, (foo, bar) to (foo, bah) 
Empty DataFrame 

을 선택하는 방법입니다 색인은 열로 저장 됨). 이것은 아주 빠를 것이다.

In [2]: store.select_column('df','one') 
Out[2]:  
0     foo 
1     foo 
2     foo 
3     foo 
4     foo 
5     foo 
6     foo 
7     foo 
8     foo 
9     foo 
10    foo 
11    foo 
12    foo 
13    foo 
14    foo 
... 
99985    foo 
99986    foo 
99987    foo 
99988    foo 
99989    foo 
99990    foo 
99991    foo 
99992    foo 
99993    foo 
99994    foo 
99995    foo 
99996    foo 
99997    foo 
99998    foo 
99999    foo 
Length: 100000, dtype: object 

당신은 정말

In [4]: %timeit store.select_column('df','one') 
100 loops, best of 3: 8.71 ms per loop 

In [5]: %timeit store.select('df',columns=['one']) 
10 loops, best of 3: 43 ms per loop 

또는 당신은 각 수준에 대한 값을하려는 경우 전체 색인

In [6]: def f(): 
    ...:  level_1 = store.select_column('df','one') 
    ...:  level_2 = store.select_column('df','two') 
    ...:  return MultiIndex.from_arrays([ level_1, level_2 ]) 
    ...: 

In [17]: %timeit f() 
10 loops, best of 3: 28.1 ms per loop 

를 얻을, 꽤 빠른 인덱스 만의 빠른 선택을하려는 경우 그것을하는 방법

In [2]: store.select_column('df','one').unique() 
Out[2]: array(['foo'], dtype=object) 

In [3]: store.select_column('df','two').unique() 
Out[3]: array(['bar', 'bah'], dtype=object) 
+0

환상적인 답변, 감사합니다. Jeff. 직접적인 대답은 store.root. *. table을 살펴 보는 것이 효과가 없다는 것입니다. 귀하의 응답에서 영감을 얻은 추가 고려 사항에서, 지름길이 없다는 것을 이해할 수 있습니다 - 선택에 모든 데이터를 고려하게해야합니다. 어떤 인덱스 값이 같은 공간을 차지할 지 알기 위해 메타 데이터를 얻으려고합니다. 설명을 위해, 내 멀티 인덱스의 모든 가능한 조합이 채워지지는 않으므로 멀티 인덱스의 레벨을 얻는 것만으로는 충분하지 않습니다. 고맙습니다. – Tony

+0

''select_column (...). unique()''도 유용 할 것입니다. 특정 레벨의 값을 얻을 수 있습니다. 유용 할 지 확신 할 수 없습니다. – Jeff

+0

메소드 I just suggest – Jeff

1

더 큰 테이블을 다루는 사람들은 Jeff가 제안한 해결책을 찾아서 Memory Error로 끝날 수 있습니다. 훨씬 더 우아한 솔루션이지만 내 경우에는 사용할 수 없습니다 (16GB RAM 데스크탑의 2e9 행 테이블, datetime 인덱스의 경우).

%%time 
#ts = h5store.select_column(h5store.keys()[0], column='timestamp').unique() 

chunkshape = int(1e7) # can vary due to machine and hdf5 

## get a list of chunks unique timestamps 
ts = [indx.index.get_level_values('timestamp').unique() 
      for indx in h5full.select(h5full.keys()[0], columns=['timestamp'], 
            stop=None, # change for a smaller selection 
            chunksize=chunkshape) 
     ] 
## drop duplicates at the the end-points 
for i in range(len(ts)-1): 
    if ts[i][-1]==ts[i+1][0]: 
     ts[i] = ts[i][:-1] 
## merge to single ndarray 
ts = np.concatenate(ts) 
: 은 내가 CSI 하나입니다 timestamp 지수 ( Float64)와, h5store 테이블로 저장 HDFStore 객체, 다중 색인 DataFrame이며, 다음 (불행하게도 우아하지 않음) 솔루션으로 돌아가 셨습니다

이 실행 시간 (2e9 행 이상) :

CPU times: user 14min 16s, sys: 2min 34s, total: 16min 50s 
Wall time: 14min 45s 
관련 문제