Создать хэш-значение для каждой строки данных с выбранными столбцами в dataframe в python pandas

Я задал аналогичный вопрос в R о создании хэш-значения для каждой строки данных. Я знаю, что могу использовать что-то вроде hashlib.md5(b'Hello World').hexdigest() для хеширования строки, но как насчет строки в кадре данных?

обновление 01

Я разработал свой код, как показано ниже:

for index, row in course_staff_df.iterrows():
        temp_df.loc[index,'hash'] = hashlib.md5(str(row[['cola','colb']].values)).hexdigest()

Мне кажется, это не очень pythonic для меня, лучшее решение?

Ответ 1

Или просто:

df.apply(lambda x: hash(tuple(x)), axis = 1)

В качестве примера:

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.rand(3,5))
print df
df.apply(lambda x: hash(tuple(x)), axis = 1)

     0         1         2         3         4
0  0.728046  0.542013  0.672425  0.374253  0.718211
1  0.875581  0.512513  0.826147  0.748880  0.835621
2  0.451142  0.178005  0.002384  0.060760  0.098650

0    5024405147753823273
1    -798936807792898628
2   -8745618293760919309

Ответ 2

Создать хеш-значение для каждой строки данных с выбранными столбцами в фрейме данных в пандах Python

Эти решения работают на всю жизнь процесса Python.

Если порядок имеет значение, один из методов будет приводить строку (объект Series) к кортежу:

>>> hash(tuple(df.irow(1)))
-4901655572611365671

Это демонстрирует порядок вопросов для хэширования кортежей:

>>> hash((1,2,3))
2528502973977326415
>>> hash((3,2,1))
5050909583595644743

Для этого каждая строка, добавленная в виде столбца, будет выглядеть следующим образом:

>>> df = df.drop('hash', 1) # lose the old hash
>>> df['hash'] = pd.Series((hash(tuple(row)) for _, row in df.iterrows()))
>>> df
           y  x0                 hash
0  11.624345  10 -7519341396217622291
1  10.388244  11 -6224388738743104050
2  11.471828  12 -4278475798199948732
3  11.927031  13 -1086800262788974363
4  14.865408  14  4065918964297112768
5  12.698461  15  8870116070367064431
6  17.744812  16 -2001582243795030948
7  16.238793  17  4683560048732242225
8  18.319039  18 -4288960467160144170
9  18.750630  19  7149535252257157079

[10 rows x 3 columns]

Если порядок не имеет значения, используйте хеш-код frozensets вместо кортежей:

>>> hash(frozenset((3,2,1)))
-272375401224217160
>>> hash(frozenset((1,2,3)))
-272375401224217160

Избегайте суммирования хэшей всех элементов в строке, поскольку это может быть криптографически небезопасным и приводить к хешам, которые выходят за пределы диапазона оригинала.

(Вы можете использовать модуль по модулю, чтобы ограничить диапазон, но это равносильно использованию собственной хэш-функции, и лучшая практика - нет.)

Вы можете создавать постоянные хеш-коды криптографического качества, например, используя sha256, а также используя модуль hashlib.

Существует некоторое обсуждение API для криптографических хеш-функций в PEP 452.

Спасибо пользователям Jamie Marshal и Discrete Lizard за их комментарии.