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

基于当前行值筛选DataFrame子集并求和生成新列的问题

问题:按行对应年份计算列总和出错

示例DataFrame

# Create a sample dataframe
df = pd.DataFrame({'num_posts': [4, 6, 3, 9, 1, 14, 2, 5, 7, 2,12],
                   'date' : ['2020-03-01', '2020-01-02', '2020-01-03', 
                            '2020-01-04', '2019-01-05', '2019-01-06', 
                            '2020-01-07', '2020-01-08', '2020-01-09', 
                            '2020-01-10','2020-01-11']})
cols=['num_posts']  

需求与现有问题

需要生成诸如“上一年最后一周num_posts总和”“上一年最后一周与上月总和的比值”这类时间维度聚合特征。当前尝试计算每行对应年份的num_posts总和,但代码未正确筛选同年份子集,所有行都返回了整个DataFrame的总和65。

现有日期处理函数:

def create_calendar_columns(df,dt):
    df['day_number']= pd.to_datetime(df[dt]).dt.dayofyear
    df['week_number']= pd.to_datetime(df[dt]).dt.isocalendar().week
    df['year']= pd.to_datetime(df[dt]).dt.year
    return df

现有求和函数:

def calculate_curr_year_sum(df,cols,dt):
    df=create_calendar_columns(df,dt)
    df[dt]=pd.to_datetime(df[dt])
    for col in cols:
         df['curr_year_sum_'+str(col)]= df.loc[df['year']==df[dt].dt.year,col].sum()  
          # 预期:计算与当前行年份相同的所有行的col总和

错误原因

代码中df['year']==df[dt].dt.year是整列的布尔比较,最终筛选出的是所有年份等于当前整个df的date列年份集合的行(实际这里date列包含2019和2020,所以该条件会匹配所有行),sum操作得到的是全局总和,没有按每行的年份单独分组计算。

解决方案

使用groupby结合transform方法,transform会将分组聚合后的结果广播回原DataFrame的每一行,正好匹配每行对应年份的总和需求。

修改后的calculate_curr_year_sum函数:

def calculate_curr_year_sum(df, cols, dt):
    df = create_calendar_columns(df, dt)
    # 避免重复转换日期(create_calendar_columns里已处理)
    for col in cols:
        # 按year分组,对col求和后广播到每行
        df[f'curr_year_sum_{col}'] = df.groupby('year')[col].transform('sum')

运行后,2019年的行对应的curr_year_sum_num_posts为1+14=15,2020年的行对应的总和为4+6+3+9+2+5+7+2+12=50,符合预期。

扩展到其他时间特征

如果要实现“上一年最后一周总和”这类特征,可以按以下思路:

  1. 先按year和week_number分组,计算每周总和
  2. 对每个年份,找到最大的week_number对应的值,作为该年最后一周总和
  3. 将上一年的最后一周总和匹配到当前年份的所有行

示例代码片段:

# 计算每周总和
df['weekly_sum'] = df.groupby(['year', 'week_number'])['num_posts'].transform('sum')
# 获取每年最后一周的总和
year_last_week_sum = df.groupby('year').apply(
    lambda x: x[x['week_number'] == x['week_number'].max()]['weekly_sum'].iloc[0]
).reset_index(name='last_week_sum')
# 匹配上一年的最后一周总和到当前行
df['prev_year_last_week_sum'] = df['year'].map(year_last_week_sum.set_index('year')['last_week_sum'].shift(1))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:37:07