Causal Impact分析报错ValueError:指定日期不在数据索引中
问题
我是一名初学者,尝试对股票数据进行简单的Causal Impact分析,但每次尝试绘制影响图时都会触发如下ValueError:
ValueError: 20201019 not present in input data index.
尽管打印DataFrame索引时能明确看到该日期,系统仍提示无法找到该日期。我已尝试了网上及文档中的所有方法但均无效,不知下一步该如何处理,恳请提供帮助。
代码与报错信息
完整代码
import yfinance as yf from causalimpact import CausalImpact import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from statsmodels.tsa.stattools import adfuller training_start = '2020-09-01' training_end = '2020-10-19' treatment_start = '2020-10-20' treatment_end = '2020-10-23' end_stock = '2020-10-24' y = ['BTC-USD'] y = yf.download(tickers = y, start = training_start, end = end_stock, interval = '1d') y = y['Adj Close'].rename('y') stocks = ['ZAL.DE', 'SQ', 'CRSP', 'JD', 'DE', 'KTOS', 'GOOG', 'TPB'] x = yf.download(tickers = stocks, start = training_start, end = end_stock, interval = '1d') x = x.iloc[:,:len(stocks)] x.columns = x.columns.droplevel() x.index = x.index.tz_localize(None) df = pd.concat([y,x], axis=1).dropna() df_training = df[df.index <= training_end] test = adfuller(x = df_training.y)[1] if test < 0.05: print('The time series is stationary') else: print('The time series is not stationary') differencing = df_training.pct_change().dropna() test = adfuller(x = differencing.y)[1] if test < 0.05: print('The time series is stationary') else: print('The time series is not stationary') plt.figure(figsize = (8,6)) sns.set(font_scale = 1.2) sns.heatmap(differencing.corr(), annot = True, fmt = '.1g', cmap = 'YlOrBr', center = True, linewidth = 1, linecolor = 'black') #plt.show() df_final = df.drop(columns = ['ZAL.DE']) df_final = df.set_index(pd.date_range(start='2020-09-01', periods=len(df_final.index))) pre_period = [pd.to_datetime(training_start), pd.to_datetime(training_end)] post_period = [pd.to_datetime(treatment_start), pd.to_datetime(treatment_end)] impact = CausalImpact(data=df_final, pre_period=pre_period, post_period=post_period) impact.plot()
报错信息
Traceback (most recent call last): File "C:\Users\MGerdes\PycharmProjects\EconometricsCausalInference\Google Causal Impact.py", line 71, in <module> impact = CausalImpact(data=df_final, pre_period=pre_period, post_period=post_period) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\MGerdes\PycharmProjects\EconometricsCausalInference\server\Lib\site-packages\causalimpact\main.py", line 206, in __init__ processed_input = cidata.process_input_data(data, pre_period, post_period, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\MGerdes\PycharmProjects\EconometricsCausalInference\server\Lib\site-packages\causalimpact\data.py", line 120, in process_input_data pre_data, post_data = process_pre_post_data(fmt_data, pre_period, post_period) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\MGerdes\PycharmProjects\EconometricsCausalInference\server\Lib\site-packages\causalimpact\data.py", line 266, in process_pre_post_data checked_pre_period = process_period(pre_period, data) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\MGerdes\PycharmProjects\EconometricsCausalInference\server\Lib\site-packages\causalimpact\data.py", line 389, in process_period raise ValueError("{point} not present in input data index.".format( ValueError: 20201019 not present in input data index.
解决方案
问题根源
你的代码存在两个关键错误,导致索引不匹配:
- df_final赋值被覆盖:你先删除了
ZAL.DE列得到df_final,但紧接着又用原始的df(包含ZAL.DE列)重新赋值覆盖了df_final,之前的列删除操作完全无效。 - 错误重置索引:你用
pd.date_range生成连续日期替换了原始的交易日索引。股票数据仅包含交易日(排除周末、节假日),而连续日期包含非交易日,导致你指定的training_end(2020-10-19)不在新的连续索引中。
修改步骤
- 保留正确的
df_final赋值,不要覆盖:
删除错误的索引重置代码,保留原始的交易日索引(yfinance下载的索引已经是正确的datetime格式,且已移除时区信息)。 - 确保
pre_period和post_period的日期存在于df_final的索引中。
修改后的代码片段
替换原代码中df_final相关的部分为:
# 正确删除ZAL.DE列,保留原始索引 df_final = df.drop(columns=['ZAL.DE']) # 直接使用原始交易日索引,不需要重置 pre_period = [pd.to_datetime(training_start), pd.to_datetime(training_end)] post_period = [pd.to_datetime(treatment_start), pd.to_datetime(treatment_end)] # 可选:验证日期是否在索引中 print(f"training_end在索引中: {pd.to_datetime(training_end) in df_final.index}") print(f"treatment_start在索引中: {pd.to_datetime(treatment_start) in df_final.index}") impact = CausalImpact(data=df_final, pre_period=pre_period, post_period=post_period) impact.plot()
额外提示
- 股票数据存在缺失值时,
dropna()会删除整行,导致索引不连续,这是正常现象,CausalImpact支持非连续的datetime索引。 - 运行前可以打印
df_final.index确认所有需要的日期都存在。
内容的提问来源于stack exchange,提问作者mhgerd01
相关产品推荐
相关产品推荐

