2013-06-08 11 views
12

Büyük miktarlarda http loglarını (80 GB +) istatistiksel işlem için bir Pandas HDFStore'a aktarıyorum. Tek bir içe aktarma dosyasında bile, içeriği yükledikçe toplu halde toplulaştırmam gerekiyor. Şu ana kadar benim taktikim, ayrıştırılmış çizgileri bir DataFrame'e okumak ve ardından DataFrame'i HDFStore'a saklamaktı. Amacım, DataStore'da tek bir anahtar için dizin anahtarının benzersiz olmasını sağlamaktır, ancak her DataFrame, kendi dizin değerini yeniden yeniden başlatır. HDFStore.append() 'ın DataFrame dizin değerlerini görmezden gelmesini ve sadece HDFStore anahtarımın varolan dizin değerlerini eklemeye devam etmesini söyleyecek bir mekanizma olacağını tahmin ediyordum ama bulamıyor gibi görünüyor. DataFrames'i nasıl içe aktarırım ve HDFStore'un varolan dizin değerlerini artırırken içerdiği dizin değerlerini dikkate almayın? Her 10 satıra toplu olarak aşağıdaki örnek kod. Doğal olarak gerçek şey daha büyük olurdu.Bir Pandas HDFStore'a büyük miktarda veri nasıl eklenir ve doğal bir benzersiz dizin elde edilir?

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

[Bu yanıtı] okuyor musunuz (http://stackoverflow.com/a/14268804/1240268)? –

cevap

13

Bunu böyle yapabilirsiniz. Sadece hile, mağaza tablosunun ilk olmadığı zaman, yani get_storer yükselecektir.

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 

Aslında ille (PyTables aracılığıyla) HDFStore olarak küresel bir benzersiz dizin, (eğer istemiyorsanız) gerekmez benzersiz numaralandırma satırların birer sağlar. Bu seçim parametrelerini her zaman ekleyebilirsiniz.

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

Harika gönderi; Bununla birlikte, bu geçici çözüm yerine, bir otomatik-endeksli dizinin olması ideal olacağı durumlar vardır (bunlar gibi). olduğu gibi: hdf5'e kaydettiğinizde, bir ignore_index = True (pd.Concat gibi) olabilir ve bunu otomatik olarak başlık altında yapar mı? Sadece bir fikir – Carst

+0

Ayrıca: büyük miktarlarda küçük dosyalar kullanıldığında, her bir bitiş eyleminin sonunda geçerli veri dizisi uzunluğuyla her seferinde geçerli satır sayısı ve her defasında bir sayı elde etmek daha iyi olacaktır (performans için çok daha iyi)). Bu belirsiz bir yorum ise, bana bildirin ve ben – Carst

+0

bir yerde çalışacağım gerçekten bunlardan birini yapmanıza gerek yok. Mağazalar dahili olarak 'numaralandırılmış' olduğundan, isterseniz satır numarasına göre seçim yapabilirsiniz, (bkz. burada) [http://pandas.pydata.org/pandas-docs/dev/io.html#advanced-queries] – Jeff