如何将cap_dict的值分配到daily_cap的每日日期键中?
问题:按规则生成每日容量字典
现有字典:
cap_dict = {pd.Timestamp('2020-06-30 00:00:00'): 40000, pd.Timestamp('2020-09-30 00:00:00'): 52000, pd.Timestamp('2020-12-31 00:00:00'): 52000, pd.Timestamp('2021-03-31 00:00:00'): 58000, pd.Timestamp('2021-06-30 00:00:00'): 89000, pd.Timestamp('2021-09-30 00:00:00'): 89000 }
需要创建名为daily_cap的字典,键为date(2020, 6, 28)至date(2022, 1, 2)范围内的每日Timestamp,值需遵循以下规则:
- 每个日期键使用
cap_dict中自身之前最新可用的对应值,例如40000分配给Timestamp('2020-06-30')至Timestamp('2020-09-29')的键,52000分配给Timestamp('2020-09-30')至Timestamp('2021-03-30')的键; - 若日期早于
cap_dict的第一个键,使用cap_dict的第一个值,例如Timestamp('2020-06-28')和Timestamp('2020-06-29')的值为40000。
原尝试代码存在逻辑错误:循环中每次都递增i,导致很快超出val_list的长度,无法正确匹配日期对应的取值。
解决方案一:使用Pandas的reindex和ffill(推荐)
利用Pandas的时间序列处理能力,这是最简洁高效的方式:
import pandas as pd from datetime import date start_date = date(2020, 6, 28) end_date = date(2022, 1, 2) # 初始化cap_dict cap_dict = {pd.Timestamp('2020-06-30 00:00:00'): 40000, pd.Timestamp('2020-09-30 00:00:00'): 52000, pd.Timestamp('2020-12-31 00:00:00'): 52000, pd.Timestamp('2021-03-31 00:00:00'): 58000, pd.Timestamp('2021-06-30 00:00:00'): 89000, pd.Timestamp('2021-09-30 00:00:00'): 89000 } # 将cap_dict转为Series并按时间索引排序 cap_series = pd.Series(cap_dict).sort_index() # 生成目标日期范围的每日时间序列 daily_dates = pd.date_range(start=start_date, end=end_date, freq='D') # 重新索引并向前填充,fill_value处理早于第一个cap日期的情况 daily_cap_series = cap_series.reindex(daily_dates, method='ffill', fill_value=cap_series.iloc[0]) # 转为字典 daily_cap = daily_cap_series.to_dict() # 打印前5个结果示例 for key in list(daily_cap.keys())[:5]: print(f"{key}: {daily_cap[key]}")
代码说明:
- 将
cap_dict转为Pandas Series并按索引排序,确保时间顺序正确; - 用
pd.date_range生成目标日期范围的每日时间戳,比rrule更简洁; reindex结合method='ffill'实现“向前填充最新值”的逻辑,fill_value指定早于第一个日期时的默认值;- 最后将Series转为字典即可得到目标结果。
解决方案二:手动遍历的正确逻辑
如果不想依赖Pandas的高级方法,也可以手动实现遍历逻辑:
import pandas as pd from datetime import date, timedelta start_date = date(2020, 6, 28) end_date = date(2022, 1, 2) cap_dict = {pd.Timestamp('2020-06-30 00:00:00'): 40000, pd.Timestamp('2020-09-30 00:00:00'): 52000, pd.Timestamp('2020-12-31 00:00:00'): 52000, pd.Timestamp('2021-03-31 00:00:00'): 58000, pd.Timestamp('2021-06-30 00:00:00'): 89000, pd.Timestamp('2021-09-30 00:00:00'): 89000 } # 将cap_dict的键值对按时间排序 sorted_cap = sorted(cap_dict.items(), key=lambda x: x[0]) cap_dates = [item[0] for item in sorted_cap] cap_values = [item[1] for item in sorted_cap] daily_cap = {} current_value = cap_values[0] # 默认初始值为第一个值 current_cap_index = 0 current_date = start_date while current_date <= end_date: t = pd.Timestamp(current_date) # 如果当前日期超过下一个cap日期,更新当前值 while current_cap_index < len(cap_dates) - 1 and t >= cap_dates[current_cap_index + 1]: current_cap_index += 1 current_value = cap_values[current_cap_index] daily_cap[t] = current_value current_date += timedelta(days=1) # 打印前5个结果示例 for key in list(daily_cap.keys())[:5]: print(f"{key}: {daily_cap[key]}")
代码说明:
- 先将
cap_dict的键值对按时间排序,确保能按顺序匹配日期区间; - 初始化
current_value为第一个值,处理早于第一个cap日期的情况; - 遍历每日日期,每次检查是否需要更新当前值(当日期超过下一个cap日期时);
- 为每个日期赋值当前值,直到遍历完所有日期。
内容的提问来源于stack exchange,提问作者Masoud180190
相关产品推荐
相关产品推荐

