使用python pandas中数据框中的选定列为每行数据创建哈希值

lok*_*art 11 python hash 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()
Run Code Online (Sandbox Code Playgroud)

对我来说这似乎不是很pythonic,任何更好的解决方案?

Nea*_*ltz 12

现在可以在pandas.util.hash_pandas_object

pandas.util.hash_pandas_object(df)
Run Code Online (Sandbox Code Playgroud)

  • 这并没有回答这个问题:“使用Python Pandas中的DataFrame中的选定列为每行数据创建哈希值” - 一行在语义上首先不是Pandas对象 - 文档说你给出的函数:“返回索引/系列/数据帧的数据哈希” - 这些都不是“行” (7认同)

cwh*_*and 8

或者干脆:

df.apply(lambda x: hash(tuple(x)), axis = 1)
Run Code Online (Sandbox Code Playgroud)

举个例子:

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
Run Code Online (Sandbox Code Playgroud)


Aar*_*all 6

使用python pandas在数据框中的选定列为数据的每一行创建哈希值

这些解决方案在Python进程的整个生命周期内都有效。

如果顺序很重要,则一种方法是将行(系列对象)强制为元组:

>>> hash(tuple(df.irow(1)))
-4901655572611365671
Run Code Online (Sandbox Code Playgroud)

这说明了元组哈希的顺序问题:

>>> hash((1,2,3))
2528502973977326415
>>> hash((3,2,1))
5050909583595644743
Run Code Online (Sandbox Code Playgroud)

为此,对于每一行,将其附加为一列如下所示:

>>> 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]
Run Code Online (Sandbox Code Playgroud)

如果顺序无关紧要,请使用frozensets的哈希而不是元组:

>>> hash(frozenset((3,2,1)))
-272375401224217160
>>> hash(frozenset((1,2,3)))
-272375401224217160
Run Code Online (Sandbox Code Playgroud)

避免对行中所有元素的哈希值求和,因为这在密码上是不安全的,并导致哈希值超出原始值的范围。

(您可以使用模来约束范围,但这相当于滚动您自己的哈希函数,而最佳实践并非如此。)

您可以永久的使用密码散列质量,例如使用SHA256,以及使用hashlib模块。

PEP 452中对用于加密哈希函数的API进行了一些讨论。

感谢用户Jamie Marshal和Discrete Lizard的评论。