Python Pandas:基于Distance值求和对应距离范围列的百分比
解决Pandas中按距离范围累计求和的问题
我来帮你搞定这个需求——根据Distance列的值,对所有完全包含在该距离以内或者包含该距离本身的百分比列进行求和。下面结合你的测试数据,一步步给出实现方案:
第一步:解析距离范围列的上下限
首先得把每个百分比列的名称(比如0-156、156-234)转换成对应的距离上下限,这样才能判断哪些列需要纳入求和范围:
import pandas as pd def parse_range(col_name): """解析距离范围列的上下限""" if col_name == '>76830': return (76830.0, float('inf')) # 把">76830"的上限设为无穷大 lower, upper = col_name.split('-') return (float(lower), float(upper)) # 初始化你的测试数据 data = [['Test1',0.36516562,19.065996,49.15094,24.344206,0.49186087,1.24217,5.2812457,0.05841639,0,0,0,0,158.4122868], ['Test2',0.20406325,10.664485,48.70978,14.885571,0.46103176,8.75815,14.200708,2.1162114,0,0,0,0,192.553074], ['Test3',0.13483211,0.6521175,6.124511,41.61725,45.0036,5.405257,1.0494527,0.012979688,0,0,0,0,1759.480042] ] df = pd.DataFrame(data, columns = ['Cell Name','0-156','156-234','234-546','546-1014','1014-1950','1950-3510','3510-6630','6630-14430','14430-30030','30030-53430','53430-76830','>76830','Distance']) # 获取所有距离范围列,并解析它们的上下限 range_columns = [col for col in df.columns if col not in ['Cell Name', 'Distance']] col_range_dict = {col: parse_range(col) for col in range_columns}
第二步:实现累计求和逻辑
这里提供两种实现方式,你可以根据数据集大小选择:
方式1:使用apply(适合小数据集,代码直观)
这种方式逻辑清晰,适合数据量不大的场景:
def calculate_cumulative(row): """计算当前行的累计百分比""" target_dist = row['Distance'] total = 0.0 for col, (lower, upper) in col_range_dict.items(): # 条件:要么范围完全在目标距离以内,要么目标距离落在该范围内 if upper <= target_dist or (lower < target_dist <= upper): total += row[col] return total # 添加新列存储结果 df['Cumulative Percentage'] = df.apply(calculate_cumulative, axis=1)
方式2:向量操作(适合大数据集,效率更高)
如果你的DataFrame行数很多,apply的速度会比较慢,推荐用向量广播的方式提升效率:
# 提取所有范围列的上下限为Series lower_bounds = pd.Series({col: val[0] for col, val in col_range_dict.items()}) upper_bounds = pd.Series({col: val[1] for col, val in col_range_dict.items()}) # 生成掩码:判断每个列是否需要纳入当前行的求和范围 dist_values = df['Distance'].values[:, None] # 转换为二维数组方便广播 mask = (upper_bounds <= dist_values) | ((lower_bounds < dist_values) & (dist_values <= upper_bounds)) # 计算每行的求和结果 df['Cumulative Percentage'] = df[range_columns].values[mask].sum(axis=1)
验证结果
运行代码后,你会得到符合预期的结果:
- Test1的累计百分比为
0.36516562 + 19.065996 = 19.43116162,和你的示例完全一致; - Test2的累计百分比为
0.20406325 + 10.664485 = 10.86854825; - Test3的累计百分比为
0.13483211 + 0.6521175 + 6.124511 + 41.61725 + 45.0036 = 93.53231061。
这样就完美实现了你要的需求!
内容的提问来源于stack exchange,提问作者Carlos Alexandre Silveira
相关产品推荐
相关产品推荐

