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

基于动态范围计算A列平均值并新增列的Pandas技术问题

解决动态范围计算A列平均值的问题

先直接说你的问题出在哪:你遇到的TypeError: Cannot index by location index with a non-integer key,是因为你在切片时犯了两个关键错误——一是用整个df['D'](一个Series)作为iloc的起始索引,而iloc只接受单个整数;二是df.loc['C'][-1]的写法完全不对,这是取C列的最后一个值(也就是'YES'),根本不是你要的当前行索引。

要实现你需要的逻辑,我们得逐行处理每一行的动态区间:当C列为YES时,用当前行的D值做起始索引,当前行的索引减1做结束索引,计算A列在这个区间的平均值;否则设为NaN。下面给你两种可行的实现方式:

方法1:用apply逐行计算(直观易读,适合小数据集)

这是最直接的写法,逻辑和你的需求完全对应,新手也能一眼看懂:

import numpy as np
import pandas as pd

test = {'A' : [100, 120, 70, 300, 190, 70, 300, 190, 70], 
        'B' : [80, 50, 64, 288, 172, 64, 288, 172, 64], 
        'C' : ['NO', 'NO', 'YES', 'NO', 'YES', 'YES', 'NO', 'YES', 'YES'], 
        'D' : [0, 1, 0, 3, 2, 2, 3, 1, 4] }
df = pd.DataFrame(data=test)

def get_dynamic_average(row):
    if row['C'] == 'YES':
        start = row['D']
        end = row.name - 1  # row.name就是当前行的索引
        # 处理边界情况:如果起始索引大于结束索引,直接返回NaN
        if start > end:
            return np.nan
        # iloc是左闭右开区间,所以要给end加1才能包含该行
        return df['A'].iloc[start:end+1].mean()
    else:
        return np.nan

df['Dyn_Ave'] = df.apply(get_dynamic_average, axis=1)

运行后你就能得到期望的结果,比如:

  • 索引2的行(C=YES):取A列0到1行的平均值,(100+120)/2=110
  • 索引8的行(C=YES):取A列4到7行的平均值,(190+70+300+190)/4=187.5

方法2:前缀和优化(适合大数据集,速度更快)

如果你的数据集很大,apply的效率会有点低,我们可以用前缀和减少重复计算:

import numpy as np
import pandas as pd

test = {'A' : [100, 120, 70, 300, 190, 70, 300, 190, 70], 
        'B' : [80, 50, 64, 288, 172, 64, 288, 172, 64], 
        'C' : ['NO', 'NO', 'YES', 'NO', 'YES', 'YES', 'NO', 'YES', 'YES'], 
        'D' : [0, 1, 0, 3, 2, 2, 3, 1, 4] }
df = pd.DataFrame(data=test)

# 计算A列的前缀和,开头加个0方便计算区间和
prefix_sum = pd.Series([0]).append(df['A'].cumsum(), ignore_index=True)

def get_dynamic_average_fast(row):
    if row['C'] == 'YES':
        start = row['D']
        end = row.name - 1
        if start > end:
            return np.nan
        # 区间和 = 前缀和[end+1] - 前缀和[start]
        total = prefix_sum[end+1] - prefix_sum[start]
        count = end - start + 1
        return total / count
    else:
        return np.nan

df['Dyn_Ave'] = df.apply(get_dynamic_average_fast, axis=1)

这种方法通过预计算前缀和,把每次求区间和的时间从O(n)降到O(1),数据量越大优势越明显。

再复盘下你的原代码问题

你的代码里:

df['Dyn_Ave'] = np.where(df['C'] == 'YES', df['A'].iloc[df['D']:df.loc['C'][-1]].mean(), np.nan)
  • df['D']是一整列数据,不是单个整数,iloc根本没法用它来切片
  • df.loc['C'][-1]取的是C列最后一个值('YES'),不是当前行的索引,完全偏离了需求

所以必须逐行获取当前行的D值和行索引,才能正确计算动态区间的平均值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:19:27