pandas groupby后nth(-2)取倒数第二行返回NaN问题排查
问题原因
赋值后pClose全为NaN的核心是索引对齐逻辑不匹配,附带一个分组键的潜在隐患:
- 长度不匹配:
df.groupby('day').nth(-2)['Close']返回的是长度等于交易日分组数的Series,索引为day值,每个day仅对应1条倒数第二行的收盘价;但原DataFrame是5分钟级别数据,每个交易日对应几十上百条K线记录,总长度远大于分组数。pandas做列赋值时会按索引精准匹配,每个day分组下仅1行能匹配到返回值,其余所有行都会被填充为NaN。你贴出的运行结果是按day分组聚合后只展示每组首行的预览,自然所有行的pClose都是NaN。 - 分组键隐患:直接用
df.index.day提取天数做分组键,跨月时会把不同月份相同日期的K线错误分到同一组,比如7月7日和8月7日的day值都是7,会被混在一起计算。
修正代码
用transform实现分组值的广播对齐,同时优化分组键避免跨月分组错误:
import pandas as pd from dateutil.relativedelta import relativedelta import yfinance as yf import datetime ticker = 'f' df = yf.download( tickers = ticker, start=datetime.datetime.now()-relativedelta(days=6), end= datetime.datetime.now(), interval="5m", progress = False ) # 用完整年月日作为分组键,避免跨月同日混淆 df['trade_date'] = df.index.date # transform会把分组计算结果广播到组内所有行,自动对齐原表索引 df['pClose'] = df.groupby('trade_date')['Close'].transform(lambda x: x.iloc[-2]) # 如需保留原有day字段可单独添加 df['day'] = df.index.day
逻辑说明
transform和直接返回聚合值的nth不同,它会保持和原DataFrame完全一致的长度,把每个分组计算得到的单值填充到该组对应的所有行,从根源上解决索引对齐失败的问题- 分组内取倒数第二行收盘价用
x.iloc[-2]实现,和你原本预期的nth(-2)逻辑完全一致 - 运行后每个交易日下的所有5分钟K线行,
pClose列都会对应该交易日倒数第二根5分钟K线的收盘价,符合预期需求。
内容的提问来源于stack exchange,提问作者Slartibartfast
相关产品推荐
相关产品推荐

