
本文介绍如何使用布尔掩码与concat组合策略,在满足条件(如country type非空)的每一行下方自动插入或更新一行,统一填入citizenship和uk等预设值,兼顾已有空行复用与新行创建逻辑。
本文介绍如何使用布尔掩码与concat组合策略,在满足条件(如country type非空)的每一行下方自动插入或更新一行,统一填入citizenship和uk等预设值,兼顾已有空行复用与新行创建逻辑。
在数据清洗与报表生成场景中,常需根据某列状态动态扩展行结构——例如当Country Type == "Origin"时,为其补充一行表示公民身份(Citizenship)的关联记录。关键挑战在于:既要复用已存在的空行(如Country Type为None的相邻行),又要在缺失时新建一行,且保持原始顺序与索引逻辑清晰。
以下为完整、健壮的实现方案:
✅ 核心思路解析
- 识别目标行:找出所有 Country Type 为 "Origin" 的行(即需触发插入逻辑的“主行”);
-
定位插入位置:
- 若下一行已存在且 Country Type.isna()(即为空行),则直接复用该行;
- 否则,在当前行下方新建一行;
- 统一赋值:对所有被选中的“插入位”(无论复用或新建),将 Country Type 设为 "Citizenship",Country 设为 "UK",其余列置为 NaN 或保留原空值。
✅ 实现代码(推荐版本)
import pandas as pd
# 构造示例数据
data = {
'Name_Type': ["Primary", "Primary", "AKA", "Primary"],
'Name': ["John", "Daniel", "Dan", "Bob"],
'Surname': ["Green", "Brown", "Brown", "White"],
'Country Type': ["Origin", "Origin", None, "Origin"],
'Country': ["UK", "UK", None, "UK"],
'Other': ["Info", None, None, "Info"]
}
df = pd.DataFrame(data)
# 步骤1:标记需处理的"主行" —— Country Type == "Origin"
mask_origin = df['Country Type'] == 'Origin'
# 步骤2:标记"可复用的空行" —— 下一行是空行(且当前行是Origin)
# m_shifted: 下一行是否为空行(用于判断是否可复用)
m_shifted = df['Country Type'].isna().shift(-1) # shift(-1) → 当前行的"下一行是否为空"
mask_reusable = mask_origin & m_shifted # 当前是Origin,且下一行为空 → 复用下一行
# 步骤3:标记需"新建行"的位置 —— 是Origin,但下一行不可复用
mask_new_row = mask_origin & ~m_shifted
# 步骤4:构建待插入的新行(仅含Country Type和Country,其余为NaN)
fill_values = {'Country Type': 'Citizenship', 'Country': 'UK'}
new_rows = pd.DataFrame(fill_values, index=df[mask_new_row].index + 0.5) # 用小数索引确保排序位置
# 步骤5:合并原始数据 + 复用行更新 + 新建行
# 先更新复用行:直接修改原df中对应下一行的值
df_updated = df.copy()
if mask_reusable.any():
# 获取复用行的索引(即当前Origin行的下一行索引)
reusable_idx = df[mask_reusable].index + 1
# 确保索引不越界
valid_reusable = reusable_idx[reusable_idx < len(df)]
df_updated.loc[valid_reusable, ['Country Type', 'Country']] = ['Citizenship', 'UK']
# 拼接:原始df + 新建行(注意sort_index稳定排序)
result = pd.concat([df_updated, new_rows]).sort_index(kind='stable').reset_index(drop=True)
print(result)✅ 输出结果
Name_Type Name Surname Country Type Country Other 0 Primary John Green Origin UK Info 1 None None None Citizenship UK None 2 Primary Daniel Brown Origin UK None 3 AKA Daniel Brown Citizenship UK None 4 Primary Bob White Origin UK Info 5 None None None Citizenship UK None
⚠️ 注意事项
- 索引稳定性:使用 sort_index(kind='stable') 避免相同索引导致的随机排序;
- 空值兼容性:fillna() 不适用于此场景(会污染非目标列),应显式控制赋值列;
- 扩展性建议:若需支持多国别/动态填充,可将 'UK' 替换为 df.loc[origin_idx, 'Country'] 实现继承;
- 性能提示:对超大数据集,避免链式索引;可改用 iloc + numpy.where 加速布尔运算。
该方法逻辑清晰、可读性强,既满足业务语义(“有空行就填,没空行就加”),又完全兼容Pandas向量化操作,适合集成至ETL流水线或自动化报告模块。


















