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

基于条件的DataFrame滚动10年均价计算及Pandas索引报错求助

问题解决:DataFrame条件均值计算与索引报错修复

我来帮你逐个搞定这两个问题——先解决你遇到的iloc索引报错,再处理核心的10年价格均值计算+标识列需求。

一、修复ValueError:iloc索引使用错误

这个报错的原因很直观:iloc是基于整数位置的索引工具,你传入了datetime对象(date1)和列名字符串,完全不符合它的参数要求,所以触发了 ValueError。

修正方案

根据你的数据结构,分两种情况处理:

情况1:df_dates2的索引是日期类型

如果你的DataFrame已经把日期设为索引,直接用loc(基于标签的索引)替代iloc就行:

date1 = '31/03/2020'
date2 = '31/03/2010'
date1 = pd.to_datetime(date1)
date2 = pd.to_datetime(date2)

# 用loc按日期标签和列名定位对应值
if df_dates2.loc[date1, 'First Occurence Consolidated'] < date2:
    print(1) # 使用consolidated数据计算均值
else:
    print(2) # 使用standalone数据计算均值

注意:你的列名First Occurence Consolidated可能有拼写错误(应该是Occurrence),如果运行时提示列不存在,先检查列名正确性。

情况2:df_dates2是默认整数索引

如果你的DataFrame用的是默认整数索引,需要先找到date1对应的行位置,再用iloc定位:

date1 = '31/03/2020'
date2 = '31/03/2010'
date1 = pd.to_datetime(date1)
date2 = pd.to_datetime(date2)

# 找到目标日期对应的行索引
row_idx = df_dates2[df_dates2['date'] == date1].index[0]
# 找到目标列的整数位置
col_idx = df_dates2.columns.get_loc('First Occurence Consolidated')

if df_dates2.iloc[row_idx, col_idx] < date2:
    print(1)
else:
    print(2)

二、实现条件式10年价格均值计算+标识列

接下来解决你的核心需求:按公司分组,过去10年如果price_consolidated无NaN值就用它,否则用price_standalone,同时新增列标注使用的数据源。

思路拆解

  1. 先确保时间序列有序:把date转成datetime类型并设为索引,保证滚动计算的准确性
  2. 按公司分组,对每个组的历史数据做滚动统计
  3. 通过滚动窗口的非NaN计数判断price_consolidated是否完整,再选择对应列计算均值
  4. 新增Price source列记录使用的数据源

完整代码实现

import pandas as pd

# 第一步:预处理数据,确保date是datetime类型且为索引
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date').sort_index()

# 定义滚动窗口参数:10年按3650天计算,min_periods=1保证数据不足时仍计算均值
window_size = 3650
min_periods = 1

# 定义分组处理函数
def process_group(group):
    # 计算过去10年price_consolidated的非NaN值数量
    consol_non_nan_count = group['price_consolidated'].shift().rolling(window=window_size, min_periods=min_periods).count()
    # 判断是否完全无NaN:计数等于窗口大小则用consolidated,否则用standalone
    use_consolidated = consol_non_nan_count == window_size
    
    # 计算两种价格的滚动均值
    mean_consol = group['price_consolidated'].shift().rolling(window=window_size, min_periods=min_periods).mean()
    mean_standalone = group['price_standalone'].shift().rolling(window=window_size, min_periods=min_periods).mean()
    
    # 条件选择最终均值,并新增数据源标识列
    group['Price mean 10 years'] = pd.where(use_consolidated, mean_consol, mean_standalone)
    group['Price source'] = pd.where(use_consolidated, 'price_consolidated', 'price_standalone')
    
    return group

# 应用分组逻辑到整个DataFrame
df = df.groupby('Company Name', group_keys=False).apply(process_group)

# 可选:恢复原索引结构(如果需要把date变回普通列)
df = df.reset_index()

代码说明

  • shift()是为了排除当前行的价格,严格计算过去10年的均值,和你之前的代码逻辑保持一致
  • 当公司历史数据不足10年时,min_periods=1会让计算继续,此时consol_non_nan_count会小于window_size,自动切换到price_standalone
  • pd.where()是矢量化操作,比循环判断高效得多,适合处理大规模数据

额外提示

如果你说的“过去10年”是指自然年的时间范围(比如从2020-03-31往前推10年到2010-03-31),而不是固定3650天(忽略闰年差异),那滚动窗口的方式可能不够准确。这种情况下需要改用按时间范围筛选的方式计算均值,如果你需要这种逻辑,可以告诉我,我再帮你调整代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 19:42:55