基于第二个DataFrame的值填充第一个DataFrame中的NaN
批量基于另一个DataFrame填充EARN列的解决方案
看起来你需要批量基于另一个DataFrame的条件填充df1里的EARN列,而且因为有数千列,绝对不能硬编码列名对吧?我给你一套通用的解决方案,完全适配大规模列的场景:
首先模拟样本数据(方便你对应自己的实际数据)
先假设你的另一个DataFrame(就叫df2吧)是长格式的,包含日期、公司代码和对应的EARN值。我们先模拟df1和df2的结构:
import pandas as pd import numpy as np # 模拟你的df1数据 df1_data = { 'Date': ['1/22/2018', '1/23/2018', '1/24/2018', '1/25/2018', '1/26/2018'], 'IBM': [163.13, 163.17, 167.26, 166.28, 166.58], 'BA': [65.94, 65.94, 67.43, 67.77, 68.37], 'CAT': [76.50, 76.51, 79.23, 80.57, 80.87], 'IBM EARN': [np.nan]*5, 'BA EARN': [np.nan]*5, 'CAT EARN': [np.nan]*5 } df1 = pd.DataFrame(df1_data) df1['Date'] = pd.to_datetime(df1['Date']) # 模拟包含EARN数据的df2(长格式) df2_data = { 'Date': ['1/22/2018', '1/23/2018', '1/24/2018', '1/22/2018', '1/23/2018', '1/24/2018', '1/22/2018', '1/23/2018', '1/24/2018'], 'Ticker': ['IBM', 'IBM', 'IBM', 'BA', 'BA', 'BA', 'CAT', 'CAT', 'CAT'], 'EARN': [12.34, 12.41, 12.55, 5.67, 5.72, 5.81, 8.92, 8.98, 9.05] } df2 = pd.DataFrame(df2_data) df2['Date'] = pd.to_datetime(df2['Date'])
核心解决方案(自动适配数千列)
1. 将df2转换为宽格式,匹配df1的EARN列结构
把df2从长格式转成和df1一致的宽格式,这样每一列就是[公司代码] EARN,方便后续合并:
df2_wide = df2.pivot(index='Date', columns='Ticker', values='EARN').add_suffix(' EARN').reset_index()
2. 合并两个DataFrame并批量填充NaN
用日期作为键合并两个DF,然后批量将df2的EARN值填充到df1的对应列中,同时保留df1中已有的非NaN值:
# 合并df1和转换后的df2_wide df1 = df1.merge(df2_wide, on='Date', how='left') # 自动提取所有主列(排除Date和带EARN的列) main_cols = [col for col in df1.columns if 'EARN' not in col and col != 'Date'] # 批量更新每一个EARN列 for col in main_cols: earn_col = f'{col} EARN' # 用df2的值填充df1的NaN,保留原有非NaN值 df1[earn_col] = df1[f'{earn_col}_y'].combine_first(df1[f'{earn_col}_x']) # 删除合并后产生的冗余列 df1.drop([f'{earn_col}_x', f'{earn_col}_y'], axis=1, inplace=True)
关键优势说明
- 完全自动化:不需要手动输入任何公司代码或列名,自动识别所有主列,完美适配数千列的场景
- 数据安全:用
combine_first只会填充df1中的NaN值,不会覆盖已有的有效数据 - 高效性:用
pivot和merge的方式处理大数据量比循环逐行处理快得多
内容的提问来源于stack exchange,提问作者J Westwood
相关产品推荐
相关产品推荐

