如何在Pandas中当指定列存在非空值时将行值合并为列表?
Pandas高效实现按Z列非空值区间合并X/Y列为列表
需求说明
当DataFrame的Z列存在非空字符串时,将该值对应的**此前连续区间(从上次Z非空值的下一行到当前Z非空行)**的X、Y列值合并为列表,生成新的DataFrame。已通过for循环实现,需更高效的Pandas原生方法。
输入示例
import pandas as pd import numpy as np df = pd.DataFrame({'X': [1,2,3,4,5,6,7,8], 'Y': [10,20,30,40,50,60,70,80], 'Z': [np.nan, np.nan, "A", np.nan, "A", "B", np.nan, np.nan]})
期望输出
# 输出结果 X Y Z 0 [1, 2, 3] [10, 20, 30] A 1 [4, 5] [40, 50] A 2 [6] [60] B
高效解决方案
利用Pandas的矢量化分组与聚合操作实现,避免循环:
# 1. 创建分组键:从后往前累积非空标记,将每个Z非空值对应的区间划分为同一组 df['group'] = df['Z'].notna().iloc[::-1].cumsum()[::-1] # 2. 按分组聚合,将X/Y转为列表,提取每组对应的Z非空值 result = df.groupby('group').agg( X=('X', list), Y=('Y', list), Z=('Z', lambda x: x.dropna().iloc[0]) ).reset_index(drop=True) # 3. 过滤无有效Z值的分组(原DataFrame末尾无对应Z非空值的行) result = result[result['Z'].notna()]
代码解释
- 分组键生成:
df['Z'].notna().iloc[::-1].cumsum()[::-1]将Z列的非空标记反转后累积求和,再反转回来,确保每个Z非空行对应的前面连续区间被分到同一组。 - 聚合操作:通过
groupby+agg批量处理,list直接将列值转为列表,lambda函数提取每组的有效Z值。 - 过滤无效分组:移除原DataFrame末尾无对应Z非空值的分组,保证结果仅包含有有效Z标记的区间。
内容的提问来源于stack exchange,提问作者Immortalz
相关产品推荐
相关产品推荐

