2016-10-11 3 views
1

効率的には、パンダのデータフレームの内容を一意かつ再現可能に識別する(バージョン管理の目的で)パンダのデータフレームのダイジェストを計算します。今は、エンディアン、dtype、インデックスの種類や列については心配しないとします。また、インデックスとカラムの両方がすでにmonotonic_increasingでソートされていると仮定します。パンダのダイジェスト

これらの値は合理的にうまくいく(やはり簡略化のため、np.float64と仮定する)。しかし、私はインデックス(と列)に問題があり、一貫したダイジェストを得られません。もちろん、インデックスをStringに変換してutf-8バイトに変換するなどの処理を行うことはできますが、それは遅いです。ここ

は、簡略化した例である。

import hashlib 
def pd_val_sha1(df): 
    x = df.values 
    if not x.flags.c_contiguous: 
     x = x.copy(order='C') 
    return hashlib.sha1(x).hexdigest() 

試験:値の

      x  y z 
s   e   id     
2012-01-01 2013-01-01 b NaN 2.0 3.0 
2015-10-27 2015-11-03 a 0.04 12.7 NaN 
2015-11-15 2016-01-01 a 7.30 -1.2 8.0 

SHA-1:アウト

import pandas as pd 
import io 

str = """s,e,id,x,y,z 
2012-01-01,2013-01-01,b,NaN,2,3 
2015-10-27,2015-11-03,a,0.04,12.7,NaN 
2015-11-15,2016-01-01,a,7.3,-1.2,8 
""" 
df = pd.read_csv(io.StringIO(str), parse_dates=[0,1], index_col=[0,1,2]).sort_index() 
df 

pd_val_sha1(df) 
>>> 'a7f0335988a967606bd030864e0e30ce03f32ec9' 

pd_val_sha1(df.head()) 
>>> 'a7f0335988a967606bd030864e0e30ce03f32ec9' 

pd_val_sha1(pd.concat([df.ix[0:2], df.ix[2:3]])) 
>>> 'a7f0335988a967606bd030864e0e30ce03f32ec9' 

これまでのところ、とても良いです。しかし、それはインデックスになると:

pd_val_sha1(df.index) 
>>> inconsistent value (re-run the example from read_csv and we'll get 
... a different result). 

私は様々な他のものを試しました。 index.valuesの代わりにまたはindex.to_native_types()またはnp.array(index.tolist())を使用していますが、根底にあるデータが異なる可能性があるため、結果は一貫しません。

これまでに働いているようなものはhashlib.sha1(np.array(df.index.format())).hexdigest()です。しかし、それは遅い。 (5000000,12)データフレームの場合は2分34秒、コンテンツ自体は900msでフィンガープリントされます。

提案がありますか?

答えて

1

時にはソリューションは...右私たちの鼻の下

from sklearn.externals import joblib 

%%time 
joblib.hash(df, hash_name='sha1') 
>>> consistent value that depends on values and axes 
Wall time: 1.66 s (for the (5000000,12) DataFrame mentioned above) 
です
関連する問題