2016-10-11 177 views
1

我想高效計算一個Pandas DataFrame的摘要,它唯一地和可重複地標識其內容(用於版本控制的目的)。現在假設我不擔心字節順序,dtypes,索引類型或列。還假設索引和列已經排序monotonic_increasing。熊貓摘要索引

事情合理地與值相符合(同樣,爲了簡化,假設np.float64)。但是我在索引(和列)方面遇到問題,沒有獲得一致的摘要。當然,我可以做一些事情,比如將索引轉換爲字符串,然後轉換爲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() 

測試:

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 

輸出:值的

      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:

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.dataindex.to_native_types()np.array(index.tolist())而不是index.values,但我仍然得到不一致的結果,因爲我認爲底層數據可能會有所不同。

到目前爲止似乎工作的一件事是hashlib.sha1(np.array(df.index.format())).hexdigest()。但它很慢,例如(5000000,12)數據幀爲2分34秒,而內容本身以900毫秒爲指紋。

有什麼建議嗎?

回答

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)