每次为Pandas DataFrame获取相同的哈希值

sg24os4d  于 2023-08-01  发布在  其他
关注(0)|答案(4)|浏览(87)

我的目标是获得DataFrame的唯一哈希值。我从.csv文件中获取。关键是每次调用hash()时都要得到相同的哈希值。
我的想法是创建函数

def _get_array_hash(arr):
    arr_hashable = arr.values
    arr_hashable.flags.writeable = False
    hash_ = hash(arr_hashable.data)
    return hash_

字符串
调用底层numpy数组,将其设置为不可变状态并获取缓冲区的哈希值。

内联UPD。

截至2016年11月8日,此版本的函数不再工作。相反,你应该使用

hash(df.values.tobytes())


请参阅注解,了解numpy数组的最有效散列属性。

内联UPD结束。

它适用于常规的pandas数组:

In [12]: data = pd.DataFrame({'A': [0], 'B': [1]})

In [13]: _get_array_hash(data)
Out[13]: -5522125492475424165

In [14]: _get_array_hash(data)
Out[14]: -5522125492475424165


但是,我尝试将其应用于从.csv文件获得的DataFrame:

In [15]: fpath = 'foo/bar.csv'

In [16]: data_from_file = pd.read_csv(fpath)

In [17]: _get_array_hash(data_from_file)
Out[17]: 6997017925422497085

In [18]: _get_array_hash(data_from_file)
Out[18]: -7524466731745902730


谁能解释一下,这怎么可能?
我可以用它创建新的DataFrame

new_data = pd.DataFrame(data=data_from_file.values, 
            columns=data_from_file.columns, 
            index=data_from_file.index)


它又起作用了

In [25]: _get_array_hash(new_data)
Out[25]: -3546154109803008241

In [26]: _get_array_hash(new_data)
Out[26]: -3546154109803008241


但我的目标是在应用程序启动期间为数据框架保留相同的哈希值,以便从缓存中检索一些值。

kx7yvsdv

kx7yvsdv1#

从Pandas 0.20.1(release notes)开始,您可以使用pandas.util.hash_pandas_objectdocs)。它为数据框架的到达行返回一个散列值(并适用于系列等。也是)。

import pandas as pd
import numpy as np

np.random.seed(42)
arr = np.random.choice(['foo', 'bar', 42], size=(3,4))
df = pd.DataFrame(arr)

print(df)
#      0    1   2    3
# 0   42  foo  42   42
# 1  foo  foo  42  bar
# 2   42   42  42   42

from pandas.util import hash_pandas_object
h = hash_pandas_object(df)

print(h)
# 0     5559921529589760079
# 1    16825627446701693880
# 2     7171023939017372657
# dtype: uint64

字符串
如果你想要一个整体哈希,请考虑以下内容:

int(hashlib.sha256(pd.util.hash_pandas_object(df, index=True).values).hexdigest(), 16)

  • hashlib.sha256()
  • hash.hexdigest()
acruukt9

acruukt92#

Joblib提供了一个针对包含numpy数组的对象优化的散列函数(例如,pandas dataframes)。

import joblib
joblib.hash(df)

字符串

wgmfuz8q

wgmfuz8q3#

我遇到了类似的问题:检查一个数据框架是否被更改,我通过散列msgpack序列化字符串来解决这个问题。这在不同的重载相同的数据之间似乎是稳定的。

import pandas as pd
import hashlib
DATA_FILE = 'data.json'

data1 = pd.read_json(DATA_FILE)
data2 = pd.read_json(DATA_FILE)

assert hashlib.md5(data1.to_msgpack()).hexdigest() == hashlib.md5(data2.to_msgpack()).hexdigest()
assert hashlib.md5(data1.values.tobytes()).hexdigest() != hashlib.md5(data2.values.tobytes()).hexdigest()

字符串

vmjh9lq9

vmjh9lq94#

这个函数似乎工作得很好:

from hashlib import sha256
def hash_df(df):
    s = str(df.columns) + str(df.index) + str(df.values)
    return sha256(s.encode()).hexdigest()

字符串

相关问题