如何在Pandas DataFrame中按条件计算指定行label列的均值?
问题描述
现有如下Pandas DataFrame:
index start end label 0 0 2 5 0 1 1 3 8 1 2 2 4 8 0 3 3 5 9 1 4 4 6 10 0 5 5 7 10 1 6 6 8 11 1 7 7 9 12 0
需要新增一列mean,该列每行的值为满足当前行start < 行j的end,且j ≤ 当前行索引i的所有行j的label列均值。
核心规则示例:
- 索引1:
mean = (label[0] + label[1])/2(3 < 5且3 < 8,符合条件的j=0、1) - 索引3:
mean = (label[1] + label[2] + label[3])/3(5不小于5,排除j=0;5 < 8、8、9,保留j=1、2、3) - 索引7:
mean = (label[4] + label[5] + label[6] + label[7])/4(9不小于5、8、8、9,排除j=0-3;9 < 10、10、11、12,保留j=4-7)
最终目标输出:
index start end label mean 0 0 2 5 0 0.000000 1 1 3 8 1 0.500000 2 2 4 8 0 0.333333 3 3 5 9 1 0.666667 4 4 6 10 0 0.500000 5 5 7 10 1 0.600000 6 6 8 11 1 0.750000 7 7 9 12 0 0.500000
尝试用cumsum实现,但无法加入条件筛选逻辑。
解决方案
方法1:循环遍历(小数据量适用)
直接遍历每行,筛选符合条件的行计算均值,逻辑直观易理解:
import pandas as pd # 构造原始数据 data = { 'index': [0,1,2,3,4,5,6,7], 'start': [2,3,4,5,6,7,8,9], 'end': [5,8,8,9,10,10,11,12], 'label': [0,1,0,1,0,1,1,0] } df = pd.DataFrame(data) # 初始化mean列 df['mean'] = 0.0 for i in df.index: current_start = df.loc[i, 'start'] # 筛选j<=i且current_start < end[j]的行 valid_rows = df[(df.index <= i) & (current_start < df['end'])] df.loc[i, 'mean'] = valid_rows['label'].mean() print(df)
方法2:广播矩阵运算(大数据量高效)
利用NumPy广播生成符合条件的布尔矩阵,批量计算均值,避免循环提升效率:
import pandas as pd import numpy as np # 构造原始数据 data = { 'index': [0,1,2,3,4,5,6,7], 'start': [2,3,4,5,6,7,8,9], 'end': [5,8,8,9,10,10,11,12], 'label': [0,1,0,1,0,1,1,0] } df = pd.DataFrame(data) # 生成start[i] < end[j]的布尔矩阵 start_end_mask = df['start'].values[:, np.newaxis] < df['end'].values # 保留j<=i的下三角区域 lower_triangle_mask = np.triu(np.ones(start_end_mask.shape, dtype=bool), k=0) # 合并两个条件 final_mask = start_end_mask & lower_triangle_mask # 计算每行的label总和与有效行数,得到均值 sum_labels = (final_mask * df['label'].values).sum(axis=1) count_rows = final_mask.sum(axis=1) df['mean'] = sum_labels / count_rows print(df)
内容的提问来源于stack exchange,提问作者Pratik Dutta
相关产品推荐
相关产品推荐

