Pandas实现:基于A列NaN生成含B列求和逻辑的新列C
解决方案:生成符合规则的Pandas DataFrame列C
实现思路
要生成满足要求的C列,核心是准确识别NaN段后的首个有效行,并计算对应NaN段的B值总和与当前行B值的和。具体步骤如下:
- 标记A列的有效行(非NaN行);
- 将连续NaN段与后续首个有效行归为同一分组;
- 计算每个分组的B值总和(即NaN段B值之和+首个有效行B值);
- 按规则填充C列:NaN行设为NaN,首个有效行赋值分组总和,其他有效行直接取B值。
完整代码
import pandas as pd import numpy as np # 构建示例DataFrame data = { 'A': [1, 1, None, None, 2, 5, None, None, 3, 4, 3, None, 5], 'B': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130] } df = pd.DataFrame(data) # 1. 标记A列的有效行 is_valid = df['A'].notna() # 2. 构建分组键:将连续NaN段与后续首个有效行绑定为同一组 # 先获取每个NaN段对应的后续首个有效行索引 valid_indices = df[is_valid].index nan_group_counts = df['A'].isna().groupby(is_valid.cumsum()).transform('count') next_valid_idx = valid_indices.repeat(nan_group_counts[~is_valid]).values # 为每行分配分组键:有效行用自身索引,NaN行用对应后续有效行索引 group_key = np.where(is_valid, df.index, next_valid_idx) # 3. 计算每个分组的B值总和 group_b_sum = df.groupby(group_key)['B'].sum() # 4. 初始化C列:有效行默认取B值,NaN行设为NaN df['C'] = df['B'].where(is_valid, np.nan) # 5. 识别NaN段后的首个有效行,替换其C值为分组总和 # 分组大小>1说明包含NaN行,对应有效行就是NaN段后的首个有效行 is_first_after_nan = is_valid & (df.groupby(group_key)['B'].transform('size') > 1) df.loc[is_first_after_nan, 'C'] = df.loc[is_first_after_nan, group_key].map(group_b_sum) # 输出结果 print(df)
代码说明
- 分组键构建:通过将NaN段映射到后续首个有效行的索引,确保每个NaN段和对应的目标有效行在同一组,方便直接计算总和。
- 首个有效行识别:通过分组大小判断,若分组包含NaN行(大小>1),则该组的有效行就是NaN段后的首个有效行。
- 规则匹配:完全贴合需求规则:
- NaN行的C值通过
where(is_valid, np.nan)直接设为NaN; - 首个有效行的C值取分组总和(即NaN段B值之和+当前行B值);
- 其他有效行的C值保持原B值。
- NaN行的C值通过
输出结果
运行代码后得到的DataFrame与示例期望输出一致(注:示例中最后一行C值为5应为笔误,正确结果应为120+130=250):
A B C 0 1.0 10 10.0 1 1.0 20 20.0 2 NaN 30 NaN 3 NaN 40 NaN 4 2.0 50 120.0 5 5.0 60 60.0 6 NaN 70 NaN 7 NaN 80 NaN 8 3.0 90 240.0 9 4.0 100 100.0 10 3.0 110 110.0 11 NaN 120 NaN 12 5.0 130 250.0
内容的提问来源于stack exchange,提问作者Mei
相关产品推荐
相关产品推荐

