如何用Pandas实现按客户分组的col2列生成?已尝试shift未果
解决方案
给定你的DataFrame:
import pandas as pd df = pd.DataFrame({ 'col1': [1, 3, 1, 2, 3, 5], 'customer': ['a', 'a', 'b', 'b', 'b', 'b'] })
我们可以通过以下步骤生成符合要求的col2列:
步骤1:标记连续重复的数值段
先按customer分组,识别出连续相同的数值组,并计算每组的长度:
# 生成连续组的标识ID df['group_id'] = df.groupby('customer')['col1'].apply(lambda x: x.ne(x.shift()).cumsum()) # 计算每个连续组的元素数量 df['group_len'] = df.groupby(['customer', 'group_id'])['col1'].transform('count')
步骤2:确定分组的目标填充值
对每个分组判断是否存在连续重复(长度≥2)的数值段,存在则取最后一个该类段的数值,不存在则标记为None:
def get_target_val(group): # 筛选出长度≥2的连续组 valid_groups = group[group['group_len'] >= 2] if not valid_groups.empty: return valid_groups['col1'].iloc[-1] return None # 为每个分组获取目标值 group_targets = df.groupby('customer').apply(get_target_val).reset_index(name='target_val') df = df.merge(group_targets, on='customer', how='left')
步骤3:填充col2列
根据目标值生成col2:存在连续重复段的分组直接填充目标值;无连续重复段的分组,前n-1行用自身col1值,最后一行用前一行的col1值:
def fill_col2(group): target = group['target_val'].iloc[0] if pd.notna(target): group['col2'] = target else: group['col2'] = group['col1'] # 最后一行替换为前一行的col1值 group['col2'].iloc[-1] = group['col1'].iloc[-2] return group # 应用填充逻辑并清理临时列 df = df.groupby('customer').apply(fill_col2).drop(columns=['group_id', 'group_len', 'target_val'])
运行后得到的结果:
col1 customer col2 0 1 a 1 1 3 a 1 2 1 b 1 3 2 b 2 4 3 b 3 5 5 b 3
处理补充示例(无分组场景)
对于单列数据:
df_single = pd.DataFrame({'col1': [1,1,1,3,5,8,10]})
用相同逻辑获取结果:
df_single['group_id'] = df_single['col1'].ne(df_single['col1'].shift()).cumsum() df_single['group_len'] = df_single.groupby('group_id')['col1'].transform('count') valid_groups = df_single[df_single['group_len'] >=2] if not valid_groups.empty: result = valid_groups['col1'].iloc[-1] else: result = df_single['col1'].iloc[-2] print(result) # 输出1
内容的提问来源于stack exchange,提问作者Ismail Awad
相关产品推荐
相关产品推荐

