Pandas合并DataFrame后仅返回NaN值问题求助
解决Pandas左连接后非连接列全为NaN的问题
问题描述
合并new_df(含date_test、year、month列)与df3(含year、month及业务列),执行左连接代码:
df_joined = pd.merge(left=new_df, right=df3, how='left', on=['year','month'])
无报错,但除year和month外所有列均为NaN,不符合预期。
new_df结构信息:
<class 'pandas.core.frame.DataFrame'> RangeIndex: 119 entries, 0 to 118 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 date_test 119 non-null datetime64[ns] 1 year 119 non-null object 2 month 119 non-null object dtypes: datetime64[ns](1), object(2)
df3结构信息:
<class 'pandas.core.frame.DataFrame'> Int64Index: 191 entries, 53 to 1297 Data columns (total 11 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 case_number 191 non-null object 1 date 191 non-null object 2 year 191 non-null object 3 country 191 non-null object 4 area 191 non-null object 5 location 191 non-null object 6 activity 191 non-null object 7 fatal_y_n 182 non-null object 8 time 172 non-null object 9 species 103 non-null object 10 month 190 non-null object dtypes: object(11)
核心原因
虽然year和month都被转为object类型,但两表中对应列的实际内容格式不匹配,导致连接时未找到匹配项。常见差异场景:
- 数值格式不一致:如
year是"2023"vs"2023.0",month是"1"vs"01" - 字符串含冗余字符:如空格(
" 12"vs"12")、换行符 - 月份表示方式不同:如
"Jan"vs"January"或"1"
排查与修复步骤
1. 检查连接列的唯一值差异
先对比两表year和month的唯一值,确认是否存在匹配项:
# 查看new_df的year、month唯一值 print("new_df year唯一值:", new_df['year'].unique()) print("new_df month唯一值:", new_df['month'].unique()) # 查看df3的year、month唯一值 print("df3 year唯一值:", df3['year'].unique()) print("df3 month唯一值:", df3['month'].unique())
2. 标准化连接列格式
根据排查结果统一格式,示例修复方案:
- 若为数字字符串带小数:转为整数再转字符串
new_df['year'] = new_df['year'].astype(float).astype(int).astype(str) df3['year'] = df3['year'].astype(float).astype(int).astype(str)
- 若月份位数不一致:统一为两位格式
new_df['month'] = new_df['month'].apply(lambda x: f"{int(x):02d}") df3['month'] = df3['month'].apply(lambda x: f"{int(x):02d}" if pd.notna(x) else x)
- 若含冗余空格:去除首尾空格
new_df['year'] = new_df['year'].str.strip() new_df['month'] = new_df['month'].str.strip() df3['year'] = df3['year'].str.strip() df3['month'] = df3['month'].str.strip()
3. 重新执行连接
格式统一后再次运行合并代码:
df_joined = pd.merge(left=new_df, right=df3, how='left', on=['year','month'])
4. 验证匹配结果
统计匹配成功的行数,确认修复效果:
print("匹配成功的行数:", df_joined['case_number'].notna().sum())
内容的提问来源于stack exchange,提问作者ricardoprata
相关产品推荐
相关产品推荐

