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

如何用Pandas函数替代for循环实现按日期匹配填充DataFrame

问题与解决方案

我希望将多个透视表的结果填充到一个DataFrame中,要求透视表中的日期与另一个DataFrame的日期匹配。我不想直接替换所有NaN值,因为这些NaN在后续会发挥作用。下方代码已实现需求,但了解到Pandas中不推荐使用for循环,请问如何仅使用Pandas函数替代循环来实现相同效果?

原实现代码

import pandas as pd

cols = ['date', 'Heavy', 'Light']
daysdf = pd.DataFrame(columns = cols)
# 设置日期范围
start = '2015-06-06'
end = '2015-07-06'
# daysdf初始包含该范围内的所有日期,Heavy和Light列均为NaN
daysdf['date']= pd.date_range(start=start, end=end)
# 模拟透视表数据
pf = pd.DataFrame({'date': ['2015-06-06', '2015-06-16', '2015-06-26', '2015-07-05'],
                   'Heavy': [450, 567, 612, 701],
                   'Light': [450, 567, 612, 701]})

# 获取pf日期在daysdf中对应的行索引
indexes = []
for p in pf['date']:
    my_index = daysdf.index[daysdf['date']==p]
    indexes.append(my_index)

# 执行填充操作
count = 0
for i in indexes:
    daysdf.iloc[i, 1] = pf.iloc[count, 1]
    daysdf.iloc[i, 2] = pf.iloc[count, 2]
    count +=1

无循环替代方案

Pandas的矢量化操作可以完全替代循环,这里提供两种高效实现方式,均保留原DataFrame中的NaN值,仅填充匹配日期的数值:

方法1:set_index + update(最简洁)

update方法会自动根据索引对齐,用pf中的非NaN值替换daysdf对应位置的NaN,完美契合需求:

import pandas as pd

cols = ['date', 'Heavy', 'Light']
start = '2015-06-06'
end = '2015-07-06'

# 初始化日期DataFrame
daysdf = pd.DataFrame({'date': pd.date_range(start=start, end=end)}, columns=cols)
# 模拟透视表数据,统一日期类型为datetime(避免字符串与日期类型不匹配)
pf = pd.DataFrame({'date': ['2015-06-06', '2015-06-16', '2015-06-26', '2015-07-05'],
                   'Heavy': [450, 567, 612, 701],
                   'Light': [450, 567, 612, 701]})
pf['date'] = pd.to_datetime(pf['date'])

# 将date设为索引,利用索引对齐完成填充
daysdf = daysdf.set_index('date')
pf = pf.set_index('date')
daysdf.update(pf)  # 仅替换匹配日期的NaN值,其余保留
# 恢复date为普通列
daysdf = daysdf.reset_index()

方法2:merge + combine_first(步骤更清晰)

通过左连接合并两个DataFrame,再用combine_first填充匹配值,适合需要查看中间过程的场景:

import pandas as pd

cols = ['date', 'Heavy', 'Light']
start = '2015-06-06'
end = '2015-07-06'

daysdf = pd.DataFrame({'date': pd.date_range(start=start, end=end)}, columns=cols)
pf = pd.DataFrame({'date': ['2015-06-06', '2015-06-16', '2015-06-26', '2015-07-05'],
                   'Heavy': [450, 567, 612, 701],
                   'Light': [450, 567, 612, 701]})

# 统一日期类型,确保匹配准确
daysdf['date'] = pd.to_datetime(daysdf['date'])
pf['date'] = pd.to_datetime(pf['date'])

# 左连接合并,保留daysdf的所有日期
merged_df = daysdf.merge(pf, on='date', how='left', suffixes=('_orig', '_pf'))
# 用pf的值填充原列的NaN,原NaN以外的内容(此处初始全为NaN)保留
merged_df['Heavy'] = merged_df['Heavy_pf'].combine_first(merged_df['Heavy_orig'])
merged_df['Light'] = merged_df['Light_pf'].combine_first(merged_df['Light_orig'])
# 提取最终需要的列
daysdf = merged_df[cols]

关键说明

  • 两种方法均为Pandas原生矢量化操作,执行效率远高于循环,且代码更简洁易维护。
  • 操作后仅填充了与pf日期匹配的数值,daysdf中其他日期的NaN值完全保留,不影响后续使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:37:11