2013-06-08 2 views
12

통계 처리를 위해 팬 로그 HDFStore에 많은 양의 http 로그 (80GB +)를 가져옵니다. 단일 가져 오기 파일 내에서도로드 할 때 콘텐츠를 일괄 처리해야합니다. 지금까지 필자가 제안한 방법은 파싱 된 라인을 DataFrame으로 읽은 다음 DataFrame을 HDFStore에 저장하는 것이 었습니다. 내 목표는 인덱스 키를 DataStore의 단일 키에 대해 고유하게하는 것이지만 각 DataFrame은 자체 인덱스 값을 다시 시작합니다. HDFStore.append()가 DataFrame 인덱스 값을 무시하고 HDFStore 키의 기존 인덱스 값을 계속 추가한다고 알리는 메커니즘이 있지만 예상대로 찾을 수없는 것으로 예상했습니다. HDFStore에서 기존 인덱스 값을 증가시키면서 DataFrames를 가져오고 거기에 포함 된 인덱스 값을 무시하려면 어떻게합니까? 샘플 코드는 10 줄마다 배치로 묶습니다. 당연히 진짜는 더 커질 것입니다.팬더 HDFStore에 대량의 데이터를 추가하고 자연스러운 고유 인덱스를 얻는 방법은 무엇입니까?

if hd_file_name: 
     """ 
     HDF5 output file specified. 
     """ 

     hdf_output = pd.HDFStore(hd_file_name, complib='blosc') 
     print hdf_output 

     columns = ['source', 'ip', 'unknown', 'user', 'timestamp', 'http_verb', 'path', 'protocol', 'http_result', 
        'response_size', 'referrer', 'user_agent', 'response_time'] 

     source_name = str(log_file.name.rsplit('/')[-1]) # HDF5 Tables don't play nice with unicode so explicit str(). :(

     batch = [] 

     for count, line in enumerate(log_file,1): 
      data = parse_line(line, rejected_output = reject_output) 

      # Add our source file name to the beginning. 
      data.insert(0, source_name)  
      batch.append(data) 

      if not (count % 10): 
       df = pd.DataFrame(batch, columns = columns) 
       hdf_output.append(KEY_NAME, df) 
       batch = [] 

     if (count % 10): 
      df = pd.DataFrame(batch, columns = columns) 
      hdf_output.append(KEY_NAME, df) 
+0

당신은 [이 답변을 읽었습니다] (http://stackoverflow.com/a/14268804/1240268)? –

답변

13

이렇게 할 수 있습니다. 트릭은 매장 테이블이 처음 존재하지 않기 때문에 get_storer가 발생합니다.

import pandas as pd 
import numpy as np 
import os 

files = ['test1.csv','test2.csv'] 
for f in files: 
    pd.DataFrame(np.random.randn(10,2),columns=list('AB')).to_csv(f) 

path = 'test.h5' 
if os.path.exists(path): 
    os.remove(path) 

with pd.get_store(path) as store: 
    for f in files: 
     df = pd.read_csv(f,index_col=0) 
     try: 
      nrows = store.get_storer('foo').nrows 
     except: 
      nrows = 0 

     df.index = pd.Series(df.index) + nrows 
     store.append('foo',df) 


In [10]: pd.read_hdf('test.h5','foo') 
Out[10]: 
      A   B 
0 0.772017 0.153381 
1 0.304131 0.368573 
2 0.995465 0.799655 
3 -0.326959 0.923280 
4 -0.808376 0.449645 
5 -1.336166 0.236968 
6 -0.593523 -0.359080 
7 -0.098482 0.037183 
8 0.315627 -1.027162 
9 -1.084545 -1.922288 
10 0.412407 -0.270916 
11 1.835381 -0.737411 
12 -0.607571 0.507790 
13 0.043509 -0.294086 
14 -0.465210 0.880798 
15 1.181344 0.354411 
16 0.501892 -0.358361 
17 0.633256 0.419397 
18 0.932354 -0.603932 
19 -0.341135 2.453220 

당신은 실제로 반드시 (PyTables를 통해) HDFStore 등 글로벌 고유 인덱스를, (당신이 하나를 원하지 않는다면) 필요가없는 고유 번호 행 하나를 제공합니다. 이러한 선택 매개 변수는 언제든지 추가 할 수 있습니다.

In [11]: pd.read_hdf('test.h5','foo',start=12,stop=15) 
Out[11]: 
      A   B 
12 -0.607571 0.507790 
13 0.043509 -0.294086 
14 -0.465210 0.880798 
+0

위대한 게시물; 그러나이 대안 대신 자동 증가 색인을 갖는 것이 이상적 일 수있는 경우 (예 : 이러한 경우)가 있습니다. as : hdf5에 저장할 때, ignore_index = True (예 : pd.Concat)를 가질 수 있으며 자동으로 두포에서 수행합니까? 그냥 아이디어 – Carst

+0

또한 : 많은 양의 작은 파일을 사용하는 경우, 추가 작업이 끝날 때마다 현재 행의 수와 현재 데이터 프레임의 길이를 매회 늘리는 것이 더 좋습니다 (실적이 훨씬 좋음).). 이것이 막연한 코멘트라면 알려주세요. 나는 어딘가에서 그것을 해결할 것입니다. – Carst

+0

당신은 정말로 이것들 중 하나를 할 필요가 없습니다. 내부적으로 상점 번호가 매겨지기 때문에 원하는 경우 행 번호로 선택할 수 있습니다 (여기를 참고하십시오) [http://pandas.pydata.org/pandas-docs/dev/io.html#advanced-queries] – Jeff