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

如何匹配DataFrame列值与查找表,用偏移累积和填充数据?

Pandas 实现匹配行后累积和填充需求

需求说明

现有两个Pandas DataFrame:

  • Data_One_df:包含日期、时间、剩余条数字段,以及多个以时间命名的空列
  • Data_Two_df:包含时间和对应的Fcst数值字段

需要实现:将Data_One_df的Time列与Data_Two_df的Time列匹配,对Data_Two_df中匹配行下一行开始的Fcst列计算累积和,将该值填充到Data_One_df中匹配列的右侧一列对应的行,且后续所有时间列的该行都保持这个值。

举个例子:Data_One_df中6:30行匹配Data_Two_df的6:30行后,取Data_Two_df中6:35到7:00的Fcst累积和(2+1+1+2+1+1=8),填充到Data_One_df的6:35列的6:30行,同时6:40、6:45等后续列的6:30行都保留8。

现有数据代码

import pandas as pd

# 创建Data_One_df
data_one = {
    "Date": ["12/1/2022"] * 7,
    "Time": ["6:30", "6:35", "6:40", "6:45", "6:50", "6:55", "7:00"],
    "Bars_left": [6, 5, 4, 3, 2, 1, 0],
    "6:30": [""] * 7,
    "6:35": [""] * 7,
    "6:40": [""] * 7,
    "6:45": [""] * 7,
    "6:50": [""] * 7,
    "6:55": [""] * 7,
    "7:00": [""] * 7,
}
Data_One_df = pd.DataFrame(data_one)

# 创建Data_Two_df
data_two = {
    "Time": ["6:30", "6:35", "6:40", "6:45", "6:50", "6:55", "7:00"],
    "Fcst": [1, 2, 1, 1, 2, 1, 1],
}
Data_Two_df = pd.DataFrame(data_two)

预期结果

import pandas as pd

data_three = {
    "Date": ["12/1/2022"] * 7,
    "Time": ["6:30", "6:35", "6:40", "6:45", "6:50", "6:55", "7:00"],
    "Bars_left": [6, 5, 4, 3, 2, 1, 0],
    "6:30": [pd.NA] * 7,
    "6:35": [8, pd.NA, pd.NA, pd.NA, pd.NA, pd.NA, pd.NA],
    "6:40": [8, 6, pd.NA, pd.NA, pd.NA, pd.NA, pd.NA],
    "6:45": [8, 6, 5, pd.NA, pd.NA, pd.NA, pd.NA],
    "6:50": [8, 6, 5, 4, pd.NA, pd.NA, pd.NA],
    "6:55": [8, 6, 5, 4, 2, pd.NA, pd.NA],
    "7:00": [8, 6, 5, 4, 2, 1, pd.NA],
}
Desired_df = pd.DataFrame(data_three)

尝试的错误代码

# 获取时间列列表
time_cols = Data_One_df.columns[3:]

# 遍历时间列并基于Data_Two_df更新值
for i, col in enumerate(time_cols):
    # 从Data_Two_df获取对应预测值
    fcst = Data_Two_df["Fcst"][i]
    # 基于预测值更新Data_One_df的值
    Data_One_df[col] = [np.nan] * fcst + list(Data_One_df[col][fcst:])

正确实现方案

思路解析

  1. 计算Data_Two_df中Fcst列的反向累积和:从最后一行往前累加,得到每个行对应的「下一行到末尾」的Fcst总和,正好匹配需求中的累积和要求
  2. 构建填充矩阵:仅在列索引大于行索引的位置填充对应累积和值,其余位置设为NaN,对应到Data_One_df中就是当前行的右侧列
  3. 将矩阵赋值到Data_One_df的时间列,完成填充

完整代码

import pandas as pd
import numpy as np

# 原数据创建(可保留用户的原有数据定义)
data_one = {
    "Date": ["12/1/2022"] * 7,
    "Time": ["6:30", "6:35", "6:40", "6:45", "6:50", "6:55", "7:00"],
    "Bars_left": [6, 5, 4, 3, 2, 1, 0],
    "6:30": [""] * 7,
    "6:35": [""] * 7,
    "6:40": [""] * 7,
    "6:45": [""] * 7,
    "6:50": [""] * 7,
    "6:55": [""] * 7,
    "7:00": [""] * 7,
}
Data_One_df = pd.DataFrame(data_one)

data_two = {
    "Time": ["6:30", "6:35", "6:40", "6:45", "6:50", "6:55", "7:00"],
    "Fcst": [1, 2, 1, 1, 2, 1, 1],
}
Data_Two_df = pd.DataFrame(data_two)

# 步骤1:计算反向累积和,shift(1)获取下一行开始的总和,最后一行无后续行填充0
rev_cumsum = Data_Two_df["Fcst"][::-1].cumsum()[::-1].shift(1).fillna(0)

# 步骤2:获取时间列列表
time_cols = Data_One_df.columns[3:]
n_rows, n_cols = len(Data_One_df), len(time_cols)

# 构建填充矩阵:列索引>行索引时填充累积和,否则为NaN
fill_matrix = np.full((n_rows, n_cols), np.nan)
for row_idx in range(n_rows):
    for col_idx in range(n_cols):
        if col_idx > row_idx:
            fill_matrix[row_idx, col_idx] = rev_cumsum.iloc[row_idx]

# 步骤3:赋值到Data_One_df
Data_One_df[time_cols] = fill_matrix

# 查看结果(可选)
print(Data_One_df)

代码说明

  • rev_cumsum:通过反向累加再反转,得到每个行对应的后续所有Fcst的总和,比如行0(6:30)对应的总和为8,行1(6:35)对应的总和为6,完全匹配预期
  • 填充矩阵逻辑:确保只有当前行的右侧列才会填充值,符合需求中"匹配列右侧一列起填充"的要求
  • 最终赋值后,每个行的右侧所有列都会保持同一个累积和值,与预期结果完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:55:02