2014-09-09 40 views
10

iki CTables Şimdiye kadar ben bu kütüphanede tarafından gerçekten şaşkın birleştirmek için nasıl bcolz. Ve bence bu büyük dosya küçük bellek içine daha büyük dosyaları yüklemek istiyorum (güzel bir çalışma Francesc, eğer bunu okuyorsanız!)Python ben bu <a href="http://nbviewer.ipython.org/github/Blosc/movielens-bench/blob/master/querying-ep14.ipynb" rel="noreferrer">notebook</a></p> <p>hafıza sıkıştırma örneklerde bcolz oynamalar

Acaba pandalarla olduğu gibi iki masalda bir araya gelme konusunda tecrübesi var mı? .merge() ve bu zamanı/hafızayı nasıl etkili yapar.

Fikirlerinizi paylaşmak için teşekkürler :-)!

+1

bcolz yineleyicilerle birlikte gelir, bu nedenle değerlendirmek için basitçe ifade edilemeyen bir şey yaparken, iki girişi yinelemeniz gerekir. Birleştirme davranışının tamamını veya daha spesifik bir şeyi mi istiyorsunuz? – mdurant

+0

@ mdurant, cevabınız için teşekkürler :-). En iyi pd.merge ile aynı fonksiyonel aralığa sahip olmak olacaktır. ama ben zaten iteratörler/jeneratörler kullanma fikrini sevdim. Bununla oynayacağım ve basit bir MapReduce ile birleştirmeyi deneyeceğim. Eğer önemli geliştirmeler gelirse burada yayınlayacağım – PlagTag

+1

Bu, yineleyici üzerinde yineleyici çalışır, gitmek için yol olabilir - çıkış (aynı zamanda bir interator) daha sonra bir bcolz'a geri borulu olmalıdır. http://toolz.readthedocs.org/en/latest/api.html#toolz.itertoolz.join – mdurant

cevap

4

SADECE SADECE GOT EDİYORUM .. büyük teşekkürler için teşekkürler itertoolz !! Burada kullandığım örnek SUPER çirkin olduğu gibi bazı sahte kod.

# here's generic pandas 
df_new = pd.merge(df1,df2) 


# example with itertoolz and bcolz 
from toolz.itertoolz import join as joinz 
import bcolz 

#convert them to ctables 
zdf1 = bcolz.ctable.fromdataframe(df1) 
zdf2 = bcolz.ctable.fromdataframe(df2) 

#column 2 of df1 and column 1 of df2 were the columns to join on 
merged = list(joinz(1,zdf1.iter(),0,zdf2.iter())) 

# where new_dtypes are the dtypes of the fields you are using 
# mine new_dtypes= '|S8,|S8,|S8,|S8,|S8' 
zdf3 = bcolz.fromiter(((a[0]+a[1]) for a in merged), dtype = new_dtypes, count = len(merged)) 

açıkçası muhtemelen bazı akıllı yolu vardır ve bu örnek çok spesifik değildir, ancak çalıştığını ve birisi ÖRNEK 21 Eki 7 de İLE fazla

DÜZENLEMEYİ dışarı inşa etmek için bir üs olarak hizmet verebilir EST

#download movielens data files from http://grouplens.org/datasets/movielens/ 
#I'm using the 1M dataset 
import pandas as pd 
import time 
from toolz.itertoolz import join as joinz 
import bcolz 

t0 = time() 
dset = '/Path/To/Your/Data/' 
udata = os.path.join(dset, 'users.dat') 
u_cols = ['user_id', 'age', 'sex', 'occupation', 'zip_code'] 
users = pd.read_csv(udata,sep='::',names=u_cols) 

rdata = os.path.join(dset, 'ratings.dat') 
r_cols = ['user_id', 'movie_id', 'rating', 'unix_timestamp'] 
ratings = pd.read_csv(rdata, sep='::', names=r_cols) 

print ("Time for parsing the data: %.2f" % (time()-t0,)) 
#Time for parsing the data: 4.72 

t0=time() 
users_ratings = pd.merge(users,ratings) 
print ("Time for merging the data: %.2f" % (time()-t0,)) 
#Time for merging the data: 0.14 

t0=time() 
zratings = bcolz.ctable.fromdataframe(ratings) 
zusers = bcolz.ctable.fromdataframe(users) 
print ("Time for ctable conversion: %.2f" % (time()-t0,)) 
#Time for ctable conversion: 0.05 

new_dtypes = ','.join([x[0].str for x in zusers.dtype.fields.values()][::-1] +[y[0].str for y in zratings.dtype.fields.values()][::-1]) 

#Do the merge with a list stored intermediately 
t0 = time() 
merged = list(joinz(0,zusers.iter(),0,zratings.iter())) 
zuser_zrating1 = bcolz.fromiter(((a[0]+a[1]) for a in merged), dtype = new_dtypes, count = len(merged)) 
print ("Time for intermediate list bcolz merge: %.2f" % (time()-t0,)) 
#Time for intermediate list bcolz merge: 3.16 

# Do the merge ONLY using iterators to limit memory consumption 
t0 = time() 
zuser_zrating2 = bcolz.fromiter(((a[0]+a[1]) for a in joinz(0,zusers.iter(),0,zratings.iter())) , dtype = new_dtypes, count = sum(1 for _ in joinz(0,zusers.iter(),0,zratings.iter()))) 
print ("Time for 2x iters of merged bcolz: %.2f" % (time()-t0,)) 
#Time for 2x iters of merged bcolz: 3.31 

Gördüğünüz gibi, benim yarattığım versiyonu ancak bellek çOK kurtaracak tek yineleyicinızı kullanarak, pandalar daha 15X yavaştır. Bu konuda yorum yapmaktan ve/veya genişletmekten çekinmeyin. bcolz, inşa edilmesi için harika bir paket gibi görünüyor.

+0

Harika teşekkürler. – PlagTag

İlgili konular