Yahoo Finance股票数据30日增长率计算结果异常求助
问题排查与解决
核心原因
所有日期增长率统计值完全相同的关键问题有两个:
- 未按股票分组计算:你调用
get_growth_df时传入的是循环最后一只股票的historyPrices(即TSLA),且即使使用合并后的stocks_df,全局shift(-i)操作会跨股票执行,破坏单只股票的时间序列连续性,导致增长率计算完全错误。 - 索引丢失导致序列混乱:合并
stocks_df时用了ignore_index=True,丢失了原时间索引,无法保证单只股票的日期按顺序排列,shift操作失去时间意义。
修正后的完整代码
1. 修正数据获取与合并逻辑
# Extracting data from yahoo finance import pandas as pd import yfinance as yf import numpy as np symbols = ['MSFT', 'HD', 'TSLA'] stocks_df = pd.DataFrame() for ticker in symbols: print(ticker) # 获取单只股票数据,保留时间索引 historyPrices = yf.download(tickers=ticker, period="max", interval="1d") historyPrices['Ticker'] = ticker historyPrices['Year'] = historyPrices.index.year historyPrices['Month'] = historyPrices.index.month historyPrices['Weekday'] = historyPrices.index.weekday historyPrices['Date'] = historyPrices.index.date # 合并时保留原索引,不重置 if stocks_df.empty: stocks_df = historyPrices else: stocks_df = pd.concat([stocks_df, historyPrices])
2. 修正增长率计算函数
# 按股票分组计算未来增长率的函数 def get_growth_df(df: pd.DataFrame) -> pd.DataFrame: # 对单只股票的时间序列计算增长率 def calculate_growth(group): # 确保组内数据按时间升序排列 group = group.sort_index() for i in range(1, 31): group[f'future_growth_{i}d'] = group['Adj Close'].shift(-i) / group['Adj Close'] return group # 按股票分组执行计算 result_df = df.groupby('Ticker').apply(calculate_growth) # 提取所有增长率列 GROWTH_KEYS = [k for k in result_df.columns if k.startswith('future_growth_')] return result_df[GROWTH_KEYS] # 生成增长率数据并查看统计结果 growth_stats = get_growth_df(stocks_df).describe() print(growth_stats)
关键修正说明
- 保留时间索引:合并数据时不再重置索引,保证单只股票的时间序列连续有序。
- 分组隔离计算:通过
groupby('Ticker')让每只股票的增长率计算基于自身历史价格,避免跨股票干扰。 - 强制排序:分组内先按时间索引排序,避免数据顺序混乱导致
shift操作出错。
预期输出示例
执行后describe()会输出各日期差异化的统计值,格式如下:
| future_growth_1d | future_growth_2d | ... | future_growth_30d | |
|---|---|---|---|---|
| count | 9876.0 | 9875.0 | ... | 9847.0 |
| mean | 1.0005 | 1.0012 | ... | 1.015 |
| std | 0.018 | 0.025 | ... | 0.08 |
| min | 0.65 | 0.62 | ... | 0.45 |
| 25% | 0.991 | 0.985 | ... | 0.97 |
| 50% | 1.000 | 1.000 | ... | 1.01 |
| 75% | 1.009 | 1.016 | ... | 1.06 |
| max | 1.15 | 1.22 | ... | 1.5 |
内容的提问来源于stack exchange,提问作者Prash
相关产品推荐
相关产品推荐

