我想高效计算一个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.data
或index.to_native_types()
或np.array(index.tolist())
而不是index.values
,但我仍然得到不一致的结果,因为我认为底层数据可能会有所不同。
到目前为止似乎工作的一件事是hashlib.sha1(np.array(df.index.format())).hexdigest()
。但它很慢,例如(5000000,12)数据帧为2分34秒,而内容本身以900毫秒为指纹。
有什么建议吗?