multiple grouped groupby group_by example columns python pandas

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()