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

如何按分组依据另一列为DataFrame创建最近值新列

按分组生成最近参考值的新列解决方案

嘿,我看你需要基于分组,从DataFrame里生成包含最近参考值的新列。结合你给出的mydata_tsample数据,我猜你想要的是为每个交易匹配时间上最近的基准refPrice(尤其是当contra_party_type为D时的refPrice,看起来这是基准更新点)。下面是具体的实现步骤:

首先,先把你的数据还原成可运行的pandas代码,方便后续操作:

import pandas as pd

# 还原你的DataFrame
data = [
    ["BUHADU", "01.04.2016", "01:10:50", 101.00, "C", 102.10],
    ["BUHADU", "01.04.2016", "02:10:50", 101.50, "C", 102.10],
    ["BUHADU", "01.04.2016", "08:10:50", 102.10, "D", 102.10],
    ["BUHADU", "01.04.2016", "09:10:50", 102.10, "C", 102.10],
    ["BUHADU", "02.04.2016", "07:12:50", 90.50, "C", 90.85],
    ["BUHADU", "02.04.2016", "09:10:55", 90.85, "D", 90.85],
    ["BUHADU", "02.04.2016", "12:11:40", 90.90, "C", 91.00],
    ["BUHADU", "02.04.2016", "12:12:02", 91.00, "D", 91.00],
    ["XDSEOI", "03.04.2016", "06:52:51", 50.00, "D", 50.00]
]

mydata_tsample = pd.DataFrame(
    data,
    columns=["cusip_id", "trd_exctn_dt", "trd_exctn_tm", "price", "contra_party_type", "refPrice"]
)

# 合并日期和时间为datetime类型,这是时间匹配的关键
mydata_tsample["trd_datetime"] = pd.to_datetime(
    mydata_tsample["trd_exctn_dt"] + " " + mydata_tsample["trd_exctn_tm"],
    format="%d.%m.%Y %H:%M:%S"
)

接下来分两种常见场景给出解决方案:

场景1:分组内向前填充最近的基准值

如果你的需求是:按cusip_id分组,让每个交易(尤其是C类型)继承时间上最近的、之前出现的D类型基准refPrice,可以用向前填充(ffill)的方式:

# 第一步:标记出所有D类型的基准refPrice,其他行设为缺失值
mydata_tsample["latest_refPrice"] = mydata_tsample.apply(
    lambda row: row["refPrice"] if row["contra_party_type"] == "D" else pd.NA,
    axis=1
)

# 第二步:按cusip_id分组,对缺失值进行向前填充
mydata_tsample["latest_refPrice"] = mydata_tsample.groupby("cusip_id")["latest_refPrice"].ffill()

# 可选:如果分组内第一个交易是C类型,ffill会留空,用bfill补全为后续的第一个基准值
# mydata_tsample["latest_refPrice"] = mydata_tsample.groupby("cusip_id")["latest_refPrice"].apply(lambda x: x.ffill().bfill())

运行后,你会得到这样的结果(截取BUHADU的部分):

cusip_idtrd_exctn_dttrd_exctn_tmpricecontra_party_typerefPricetrd_datetimelatest_refPrice
BUHADU01.04.201601:10:50101.0C102.12016-04-01 01:10:50
BUHADU01.04.201602:10:50101.5C102.12016-04-01 02:10:50
BUHADU01.04.201608:10:50102.1D102.12016-04-01 08:10:50102.1
BUHADU01.04.201609:10:50102.1C102.12016-04-01 09:10:50102.1

场景2:精确匹配时间上最近的基准(支持跨日期)

如果需要更精准的时间匹配——比如即使跨日期,也要找到整个cusip_id分组内时间最接近当前交易的基准refPrice,推荐使用merge_asof方法:

# 提取所有D类型的基准数据,重命名列方便后续合并
ref_benchmarks = mydata_tsample[mydata_tsample["contra_party_type"] == "D"].rename(
    columns={"refPrice": "latest_refPrice", "trd_datetime": "benchmark_datetime"}
)[["cusip_id", "benchmark_datetime", "latest_refPrice"]]

# 使用merge_asof按cusip_id分组,匹配最近的不晚于当前交易时间的基准
mydata_tsample = pd.merge_asof(
    mydata_tsample.sort_values("trd_datetime"),
    ref_benchmarks.sort_values("benchmark_datetime"),
    by="cusip_id",
    left_on="trd_datetime",
    right_on="benchmark_datetime",
    direction="backward"  # 可选:"forward"找之后最近的,"nearest"找最接近的
)

这个方法的灵活性更高,你可以通过修改direction参数来调整匹配逻辑:

  • backward:找时间上早于或等于当前交易的最近基准
  • forward:找时间上晚于或等于当前交易的最近基准
  • nearest:找时间上最接近当前交易的基准(无论前后)

额外提示

  • 一定要先把日期和时间合并成datetime类型,否则时间排序和匹配会出错;
  • 如果你的分组依据是cusip_id + trd_exctn_dt(即每天的基准只在当天生效),只需要把groupby的参数改成["cusip_id", "trd_exctn_dt"],或者在merge_asof的by参数里加上trd_exctn_dt即可;
  • 对于分组内没有匹配到基准的行,可以根据业务需求填充默认值,比如mydata_tsample["latest_refPrice"] = mydata_tsample["latest_refPrice"].fillna(0)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:42:38