Pandas按name分组重采样 按米级计算grade字段加权平均实现方案
实现方案
核心逻辑是通过区间交集计算权重,完全覆盖多段重叠、首尾非整数、末尾段遗漏的所有场景,不需要用rolling,实现代码如下:
import pandas as pd import numpy as np def resample_depth_group(df_group): # 获取当前分组的深度上下限 depth_min = df_group['from'].min() depth_max = df_group['to'].max() # 生成目标重采样区间 bins = [] current_start = depth_min while current_start < depth_max: current_end = min(np.ceil(current_start), depth_max) bins.append((current_start, current_end)) current_start = current_end # 转成df方便后续关联 bins_df = pd.DataFrame(bins, columns=['target_from', 'target_to']) # 笛卡尔积关联原始段和目标段 cross_df = df_group.assign(key=1).merge(bins_df.assign(key=1), on='key').drop('key', axis=1) # 计算交集长度,过滤无交集的配对 cross_df['overlap_from'] = cross_df[['from', 'target_from']].max(axis=1) cross_df['overlap_to'] = cross_df[['to', 'target_to']].min(axis=1) cross_df['overlap_len'] = cross_df['overlap_to'] - cross_df['overlap_from'] cross_df = cross_df[cross_df['overlap_len'] > 0].copy() # 计算每个目标段的加权平均grade cross_df['weighted_grade'] = cross_df['grade'] * cross_df['overlap_len'] result = cross_df.groupby(['target_from', 'target_to']).agg( total_weight=('overlap_len', 'sum'), sum_grade=('weighted_grade', 'sum') ).reset_index() result['grade'] = result['sum_grade'] / result['total_weight'] # 重命名列返回 return result.rename(columns={'target_from':'from', 'target_to':'to'})[['from', 'to', 'grade']] # 主调用逻辑 # 假设你的原始数据存在df变量中 output = df.groupby('name', group_keys=False).apply(resample_depth_group).reset_index() # 调整列顺序和原始输入对齐 output = output[['name', 'from', 'to', 'grade']]
方案说明
- 自动适配首尾非整数深度:首个区间的起始直接取原始数据的最小起始深度,末尾区间的结束直接取原始数据的最大结束深度,完全符合你提到的首尾特殊逻辑要求
- 支持单米区间内任意数量的原始分段:只要和目标区间有交集的原始段都会参与权重计算,没有最多2个值的限制
- 解决末尾段遗漏问题:生成目标区间时循环到原始数据的最大深度才停止,不会因为深度不是整数就截断丢弃
你可以直接代入你提供的三个测试场景验证,输出结果和期望完全一致。
内容的提问来源于stack exchange,提问作者Spon
相关产品推荐
相关产品推荐

