在Python Pandas中为DataFrame选定列的每行数据创建哈希值
我在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()
我觉得这段代码看起来不是很符合Python的风格,有没有更好的解决方案呢?
5 个回答
在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后在另一个地方使用这些数据。这就像你从冰箱拿出食材,然后在厨房里做饭一样。
有些时候,我们会遇到一些问题,比如数据没有按照我们想要的方式出现。这就像你打开冰箱,发现里面的食材不够或者过期了,这时候你就需要想办法解决这个问题。
在编程里,解决这些问题的方法有很多,比如使用不同的工具或者写一些代码来处理这些数据。就像你可以选择不同的食谱来做饭,或者用不同的厨具来帮助你完成任务。
总之,编程就像做饭一样,需要我们不断尝试和调整,才能做出美味的“菜肴”。
df.set_index(pd.util.hash_pandas_object(df), drop=False, inplace=True)
我根据问题中提供的代码,做了一些调整:
new_df2 = df.copy()
key_combination = ['col1', 'col2', 'col3', 'col4']
new_df2.index = list(map(lambda x: hashlib.sha1('-'.join([col_value for col_value in x]).encode('utf-8')).hexdigest(), new_df2[key_combination].values))
在Python的pandas库中,为数据框中选定的列的每一行创建哈希值。
这些方法在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]
如果顺序不重要,可以使用冻结集合的哈希值,而不是元组的哈希值:
>>> hash(frozenset((3,2,1)))
-272375401224217160
>>> hash(frozenset((1,2,3)))
-272375401224217160
要避免将行中所有元素的哈希值相加,因为这样可能会导致安全性问题,并生成超出原始范围的哈希值。
(你可以使用取模来限制范围,但这就相当于自己实现一个哈希函数,最佳做法是不要这样做。)
你可以创建永久的高质量加密哈希,比如使用sha256,也可以使用hashlib模块。
关于加密哈希函数的API讨论可以参考PEP 452。
感谢用户Jamie Marshal和Discrete Lizard的评论。
现在可以在 pandas.util.hash_pandas_object
中找到这个功能:
pandas.util.hash_pandas_object(df)
或者简单来说:
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