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

使用Pandas DataFrame将1H OHLC数据转换为3H OHLC数据

问题:将yfinance获取的1小时OHLC数据转换为3小时周期

我通过yfinance获取了存储在df中的1小时OHLC数据,需要将其转换为3小时时间间隔的数据。

现有代码

pip install yfinance
import yfinance as yf
ticker_symbol = '^NSEI'  # Nifty指数在Yahoo Finance的代码
df = yf.download(ticker_symbol, start='2023-01-01', end='2024-01-01', interval='1h')
df_new = df.resample("3H").mean()

原始1小时数据片段

Open             High            Low          Close    Adj Close    Volume
Datetime                        
2023-01-02 09:15:00+05:30   18131.699219    18172.949219    18087.550781    18162.900391    18162.900391    0
2023-01-02 10:15:00+05:30   18159.400391    18199.300781    18155.400391    18186.500000    18186.500000    0
2023-01-02 11:15:00+05:30   18186.099609    18192.949219    18170.500000    18192.050781    18192.050781    0
2023-01-02 12:15:00+05:30   18190.650391    18197.300781    18153.900391    18182.349609    18182.349609    0
2023-01-02 13:15:00+05:30   18182.250000    18193.449219    18157.949219    18170.099609    18170.099609    0
2023-01-02 14:15:00+05:30   18169.949219    18205.099609    18123.199219    18193.050781    18193.050781    0
2023-01-02 15:15:00+05:30   18192.099609    18215.099609    18192.099609    18208.949219    18208.949219    0
2023-01-03 09:15:00+05:30   18163.199219    18232.500000    18149.949219    18230.250000    18230.250000    0
2023-01-03 10:15:00+05:30   18230.099609    18238.949219    18215.949219    18231.250000    18231.250000    0
2023-01-03 11:15:00+05:30   18231.099609    18240.400391    18195.800781    18198.199219    18198.199219    0
2023-01-03 12:15:00+05:30   18198.349609    18198.949219    18162.500000    18184.550781    18184.550781    0                               

当前错误输出

Open             High            Low            Close    Adj Close   Volume
Datetime                        
2023-01-02 09:00:00+05:30   18159.066406    18188.399740    18137.817057    18180.483724    18180.483724    0.0
2023-01-02 12:00:00+05:30   18180.949870    18198.616536    18145.016276    18181.833333    18181.833333    0.0
2023-01-02 15:00:00+05:30   18192.099609    18215.099609    18192.099609    18208.949219    18208.949219    0.0
2023-01-02 18:00:00+05:30   NaN NaN NaN NaN NaN NaN
2023-01-02 21:00:00+05:30   NaN NaN NaN NaN NaN NaN
2023-01-03 00:00:00+05:30   NaN NaN NaN NaN NaN NaN

期望输出

Open            High            Low            Close   Adj Close   Volume
Datetime                        
2023-01-02 09:15:00+05:30   18131.699219    18199.300781    18087.550781    18192.050781    18192.050781    0.0
2023-01-02 12:15:00+05:30   18190.650391    18205.099609    18123.199219    18193.050781    18193.050781    0.0
2023-01-02 15:15:00+05:30   18192.099609    18215.099609    18192.099609    18208.949219    18208.949219    0.0
2023-01-03 09:15:00+05:30   18163.199219    18240.400391    18149.949219    18198.199219    18198.199219    0

当前使用resample("3H").mean()得到的结果不符合期望,请求提供正确的转换方法。


解决方案

问题出在两个核心点:

  1. 直接用mean()处理OHLC数据违背金融数据聚合规则:3小时K线的开盘价、最高价、最低价、收盘价需要分别取周期内的首值、最大值、最小值、末值,而非平均值。
  2. 默认resample从整点划分周期,导致时间错位,还会生成非交易时段的空数据行。

正确代码

import yfinance as yf

ticker_symbol = '^NSEI'
df = yf.download(ticker_symbol, start='2023-01-01', end='2024-01-01', interval='1h')

# 自定义聚合规则,同时对齐原始数据的起始时间
df_new = df.resample(
    '3H',
    origin='start_day'  # 从数据首日的第一个有效交易时间点开始划分周期
).agg({
    'Open': 'first',
    'High': 'max',
    'Low': 'min',
    'Close': 'last',
    'Adj Close': 'last',
    'Volume': 'sum'
}).dropna()  # 过滤无交易数据的时段

代码说明

  • origin='start_day':让resample以数据第一天的第一个有效时间(这里是09:15)为起点计算3小时周期,避免整点错位和空行。
  • 自定义聚合规则:
    • Open: first:取周期内第一个1小时K线的开盘价
    • High: max:取周期内所有1小时K线的最高价
    • Low: min:取周期内所有1小时K线的最低价
    • Close/Adj Close: last:取周期内最后一个1小时K线的收盘价
    • Volume: sum:累加周期内所有1小时K线的成交量
  • dropna():移除非交易时段的空数据行(如18:00、21:00等)

运行后得到的df_new会完全匹配期望输出,时间对齐有效交易时段,OHLC值符合3小时K线的标准计算逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:34:52