You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何不同Pandas DataFrame中相同邮箱地址的哈希值不同?

问题

在使用Pandas处理数据时,对两个DataFrame(df1和df2)中的邮箱地址列进行哈希操作,随后将两个DataFrame按ID进行内连接,发现相同的邮箱地址对应的哈希值却不相同。

复现代码

import pandas as pd

### Boring part to import the data ###

# define table 1 as df1
df1 = pd.DataFrame([[2, 'random.email@fjjd.com'], [6, 'different.email@u8888ueend.dskjs'], [7, 'random.email@dsju.c'], [8, 'same.email@dkicj.c'], [200, 'different.email@cjhs.oo'], [18, 'random.email@siidjd.dd'], [19, 'random.email@dsjds.j']])
df1 = df1.set_axis(['ID1', 'email 1'], axis=1)

# define table 2 as df2
df2 = pd.DataFrame([[100, 'new.email@jsscd.d'], [6, 'different.email@uueend.dskjs'], [99, 'new.email@djjsd.conm'], [10, 'new.email@jhhs.co'], [115, 'new.email@dsjjdsds.cod'], [116, 'new.email@dsjkjds.ckk'], [8, 'same.email@dkicj.c'], [200, 'different.email@jdsjd.co']])
df2 = df2.set_axis(['ID2', 'email 2'], axis=1)

### End part to import the data ###

### Fun part now... ###

# hash the emails in each row of df1?
df1['hash 1'] = pd.util.hash_pandas_object(df1['email 1'].astype(str))  

# hash the emails in each row of df2?
df2['hash 2'] = pd.util.hash_pandas_object(df2['email 2'].astype(str)) 

# perform an inner join of df1 and df2 about their IDs, ID1 and ID2 respectively
df3 = pd.merge(df1, df2, how='inner', left_on='ID1', right_on='ID2') 

# add an email comparison column
df3['same email'] = df3['email 1'] == df3['email 2']

# add a hash comparison column
df3['same hash'] = df3['hash 1'] == df3['hash 2']

# print the table...
print(df3)

执行结果

ID1                           email 1                hash 1  ID2                       email 2                hash 2  same email  same hash
0    6  different.email@u8888ueend.dskjs  18381560226251184406    6  different.email@uueend.dskjs  16113553761483526335       False      False
1    8                same.email@dkicj.c   5780217243550696535    8            same.email@dkicj.c   6939369575697951555        True      False
2  200           different.email@cjhs.oo  13252009090739560311  200      different.email@jdsjd.co   1942861278265138167       False      False

可见ID=8的行中邮箱地址完全相同,但对应的哈希值却不一致。


原因与解决方法

问题根源

你误用了哈希函数:pd.util.hash_pandas_object() 的作用是对整个Pandas对象(比如Series)生成一个整体哈希值,而非对Series内的每个元素单独哈希。当你将这个函数的结果赋值给新列时,Pandas会把单一哈希值广播到整列所有行,不同Series(即便包含相同元素)的整体哈希值自然不同,导致相同邮箱的哈希结果不一致。

正确做法

要对每个邮箱字符串单独哈希,需使用Python内置hash()函数,或更稳定的加密哈希函数(如hashlib中的MD5/SHA256)。以下是修正后的代码:

方法1:使用Python内置hash()

import pandas as pd

# 数据导入部分不变...

# 对每个邮箱单独哈希
df1['hash 1'] = df1['email 1'].astype(str).apply(hash)
df2['hash 2'] = df2['email 2'].astype(str).apply(hash)

# 后续连接、对比代码不变
df3 = pd.merge(df1, df2, how='inner', left_on='ID1', right_on='ID2')
df3['same email'] = df3['email 1'] == df3['email 2']
df3['same hash'] = df3['hash 1'] == df3['hash 2']

print(df3)

方法2:使用加密哈希(跨会话/环境一致)

内置hash()的结果受Python会话影响,不同会话可能得到不同结果。若需要稳定的哈希值,推荐使用hashlib:

import pandas as pd
import hashlib

def str_hash(s):
    # 将字符串转为字节,计算SHA256哈希后转为十六进制字符串
    return hashlib.sha256(s.encode('utf-8')).hexdigest()

# 数据导入部分不变...

df1['hash 1'] = df1['email 1'].astype(str).apply(str_hash)
df2['hash 2'] = df2['email 2'].astype(str).apply(str_hash)

# 后续连接、对比代码不变
df3 = pd.merge(df1, df2, how='inner', left_on='ID1', right_on='ID2')
df3['same email'] = df3['email 1'] == df3['email 2']
df3['same hash'] = df3['hash 1'] == df3['hash 2']

print(df3)

修正后结果

两种方法都会让ID=8的行中,相同邮箱的哈希值完全一致,same hash列会显示True。


内容的提问来源于stack exchange,提问作者BieberFantasy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 16:25:31