如何在Pandas DataFrame交易日插入周末/节假日日期?多股票场景报错处理
在Pandas DataFrame中为多只股票插入非交易日日期的问题解决
我尝试在记录股市交易日(日期与收盘价)的Pandas DataFrame中插入周末/节假日日期。单只股票的场景可正常运行,但多只股票的场景执行时触发错误。
示例1:单只股票场景(执行成功)
import pandas as pd df1 = pd.DataFrame({'date' : ['2023-08-11', '2023-08-14'], 'close' : [177.79, 179.46], 'stock' : ['APPL','APPL']}) df1['date'] = pd.to_datetime(df1['date'], format ="%Y-%m-%d") # 原始数据 # date close stock # 0 2023-08-11 177.79 APPL # 1 2023-08-14 179.46 APPL df1.set_index('date', inplace=True) df1_fin = df1.reindex(pd.date_range(df1.index.min(), df1.index.max())).sort_index(ascending=True).reset_index().rename(columns={'index': 'date'}) # 处理后结果 # date close stock # 0 2023-08-11 177.79 APPL # 1 2023-08-12 NaN NaN # 2 2023-08-13 NaN NaN # 3 2023-08-14 179.46 APPL
示例2:多只股票场景(执行失败)
执行以下代码时,报错ValueError: cannot reindex on an axis with duplicate labels:
import pandas as pd df1 = pd.DataFrame({'date' : ['2023-08-11', '2023-08-14','2023-08-11', '2023-08-14'], 'close' : [177.79, 179.46, 321.01, 324.04], 'stock' : ['APPL','APPL','MSFT','MSFT']}) df1['date'] = pd.to_datetime(df1['date'], format ="%Y-%m-%d") # 原始数据 # date close stock # 0 2023-08-11 177.79 APPL # 1 2023-08-14 179.46 APPL # 2 2023-08-11 321.01 MSFT # 3 2023-08-14 324.04 MSFT df1.set_index('date', inplace=True) df1_fin = df1.reindex(pd.date_range(df1.index.min(), df1.index.max())).sort_index(ascending=True).reset_index().rename(columns={'index': 'date'})
期望输出
date close stock 0 2023-08-11 177.79 APPL 1 2023-08-12 NaN NaN 2 2023-08-13 NaN NaN 3 2023-08-14 179.46 APPL 4 2023-08-11 321.01 MSFT 5 2023-08-12 NaN NaN 6 2023-08-13 NaN NaN 7 2023-08-14 324.04 MSFT
问题原因与解决方案
问题原因
多只股票场景下,将date设为索引后会出现重复的日期标签(不同股票对应同一日期),而reindex方法无法处理带有重复标签的索引,因此抛出错误。
解决方案
按股票代码分组,对每个分组单独执行重索引操作,最后合并所有分组的结果。同时填充每个分组中stock列的缺失值(因为每个分组对应单一股票):
import pandas as pd df1 = pd.DataFrame({'date' : ['2023-08-11', '2023-08-14','2023-08-11', '2023-08-14'], 'close' : [177.79, 179.46, 321.01, 324.04], 'stock' : ['APPL','APPL','MSFT','MSFT']}) df1['date'] = pd.to_datetime(df1['date'], format ="%Y-%m-%d") # 定义分组处理函数 def process_group(group): # 生成当前股票的日期范围 date_range = pd.date_range(group['date'].min(), group['date'].max()) # 设置索引并重索引 group_processed = group.set_index('date').reindex(date_range).reset_index().rename(columns={'index': 'date'}) # 填充stock列的缺失值(每个分组对应单一股票) group_processed['stock'] = group_processed['stock'].ffill().bfill() return group_processed # 分组处理并合并结果 df1_fin = df1.groupby('stock').apply(process_group).reset_index(drop=True) print(df1_fin)
执行后即可得到符合期望的输出。
内容的提问来源于stack exchange,提问作者user3685918
相关产品推荐
相关产品推荐

