Python中基于pic_code合并df61与df_petsy_gz失败,结果全为NaN
排查DataFrame合并后大量NaN的问题
遇到这种明明应该有大量匹配却全是NaN的情况,大概率是字符串字段的隐性差异导致的——毕竟几百万行的数据,肉眼很难发现细节问题。我给你一步步拆解排查思路:
1. 先排查最常见的「空格/不可见字符」问题
虽然两个字段都是object类型,但很可能其中一方的pic_code前后带了空格、制表符甚至换行符,看起来一样实际不一样。先做清洗再试合并:
import pandas as pd # 给两个DataFrame的pic_code做清洗:去除前后空白字符 df61['pic_code_clean'] = df61['pic_code'].str.strip() df_petsy_gz['pic_code_clean'] = df_petsy_gz['pic_code'].str.strip() # 用清洗后的字段做左连接(保留df61的所有行) merged_test = pd.merge(df61, df_petsy_gz, on='pic_code_clean', how='left') # 检查匹配情况 matched_rows = merged_test.dropna(subset=[col for col in merged_test.columns if col not in df61.columns]) print(f"清洗后匹配到的行数: {len(matched_rows)},占比: {len(matched_rows)/len(df61):.2%}")
如果这次匹配率上来了,那就是空白字符的锅,直接用清洗后的字段合并就行。
2. 检查字符串长度是否一致
如果清洗后还是没匹配,那看看两个字段的字符串长度分布:
# 查看df61中pic_code的长度统计 print("df61的pic_code长度分布:") print(df61['pic_code'].str.len().value_counts()) # 查看df_petsy_gz的pic_code长度统计 print("\ndf_petsy_gz的pic_code长度分布:") print(df_petsy_gz['pic_code'].str.len().value_counts())
如果两边长度不一样,比如一边是32位,一边是31位,那肯定匹配不上。这种情况通常是数据导入时的问题:比如其中一个表的pic_code被误转成数字类型(丢失了开头的0),再转回字符串就少了位数。解决办法是把数字转成字符串时补全前导0,比如:
# 假设正确长度是32位,给短的补0 df_petsy_gz['pic_code_clean'] = df_petsy_gz['pic_code'].astype(str).str.zfill(32)
3. 排查隐藏的Unicode不可见字符
还有一种更隐蔽的情况:字符串里混了零宽空格、全角空格这类肉眼看不到的字符。可以用repr()函数查看字符串的原始表示:
# 取df61的第一个pic_code,看原始结构 print("df61第一个pic_code的原始表示:") print(repr(df61['pic_code'].iloc[0])) # 去df_petsy_gz里搜这个代码(先去掉空格),看匹配到的原始结构 target = df61['pic_code'].iloc[0].strip() found = df_petsy_gz[df_petsy_gz['pic_code'].str.contains(target)] if not found.empty: print("\ndf_petsy_gz中匹配到的原始表示:") print(repr(found['pic_code'].iloc[0]))
如果输出里有\u200b(零宽空格)或者\xa0(全角空格)这类字符,就用str.replace()把它们去掉:
# 去除零宽空格和全角空格 df61['pic_code_clean'] = df61['pic_code'].str.replace('\u200b', '').str.replace('\xa0', '').str.strip() df_petsy_gz['pic_code_clean'] = df_petsy_gz['pic_code'].str.replace('\u200b', '').str.replace('\xa0', '').str.strip()
4. 最后检查合并参数是否正确
确认一下你用的合并方式:如果用的是how='inner',那只有两边都有的行才会保留,要是其中一方有大量缺失值,结果会很少;但你说有大量NaN,应该是用了how='left'或者right',这个问题不大,但还是确认一下on参数是不是指定了正确的字段。
按这个流程排查下来,大概率能解决问题——毕竟几百万行的数据,逻辑上没问题的话,就是字符串的隐性格式差异在搞鬼。
内容的提问来源于stack exchange,提问作者M Sanders
相关产品推荐
相关产品推荐

