python - grouped - Obtenga el mismo valor hash para un Pandas DataFrame cada vez
pandas grouped by (2)
A partir de Pandas 0.20.1, puede utilizar el hash_pandas_object
( código fuente ) poco conocido (y mal documentado) que se hizo público recientemente en pandas.utils
. Devuelve un valor de hash para la fila de alcance del marco de datos (y también funciona en series, etc.)
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
Siempre puedes hacer hash_pandas_object(df).sum()
si quieres un hash general de todas las filas.
Mi objetivo es obtener un valor de hash único para un DataFrame. Lo obtengo de archivo .csv. Todo el punto es obtener el mismo hash cada vez que llamo a hash () en él.
Mi idea fue que yo creara la función.
def _get_array_hash(arr):
arr_hashable = arr.values
arr_hashable.flags.writeable = False
hash_ = hash(arr_hashable.data)
return hash_
es decir, llamar a una matriz numpy subyacente, establecerla en estado inmutable y obtener el hash del búfer.
INLINE UPD.
A partir del 08.11.2016, esta versión de la función ya no funciona. En su lugar, debes usar
hash(df.values.tobytes())
Vea los comentarios de la propiedad más eficiente para hacer hash para la matriz numpy .
FIN DE LA LINEA EN LINEA.
Funciona para la matriz de pandas regular:
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
Pero luego trato de aplicarlo a DataFrame obtenido de un archivo .csv:
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
¿Alguien me puede explicar, cómo es eso posible?
Puedo crear un nuevo DataFrame fuera de él, como
new_data = pd.DataFrame(data=data_from_file.values,
columns=data_from_file.columns,
index=data_from_file.index)
y funciona de nuevo
In [25]: _get_array_hash(new_data)
Out[25]: -3546154109803008241
In [26]: _get_array_hash(new_data)
Out[26]: -3546154109803008241
Pero mi objetivo es preservar el mismo valor hash para un marco de datos en todos los lanzamientos de aplicaciones con el fin de recuperar algo de valor de la memoria caché.
Tuve un problema similar: verifique si se cambia un marco de datos y lo resolví mediante el hashing de la cadena de serialización msgpack. Esto parece estable entre diferentes recargas de los mismos datos.
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()