按Col1分组后根据Col2条件填充DataFrame新列的实现需求
按分组规则生成新列的实现方案
需求描述
对表格按Col1字段分组,根据每组Col2是否包含值Y,生成新列New_Col:
- 若分组内存在
Col2=Y的行,将该行对应的Col3值填充至该组所有行的New_Col - 若分组内无
Col2=Y的行,直接将每行的Col3值填入New_Col
原始数据
| index | Col1 | Col2 | Col3 |
|---|---|---|---|
| 0 | 1 | X | ABC |
| 1 | 1 | Y | XX |
| 2 | 1 | X | QW |
| 3 | 2 | X | VB |
| 4 | 2 | X | AY |
| 5 | 3 | X | MM |
| 6 | 3 | X | YY |
| 7 | 3 | Y | XX |
期望输出
| index | Col1 | Col2 | Col3 | New_Col |
|---|---|---|---|---|
| 0 | 1 | X | ABC | XX |
| 1 | 1 | Y | XX | XX |
| 2 | 1 | X | QW | XX |
| 3 | 2 | X | VB | VB |
| 4 | 2 | X | AY | AY |
| 5 | 3 | X | MM | XX |
| 6 | 3 | X | YY | XX |
| 7 | 3 | Y | XX | XX |
Pandas实现代码
下面是两种可行的实现方式:
方法一:分组自定义函数
通过groupby.apply结合自定义函数处理每个分组,逻辑直观清晰:
import pandas as pd # 构建原始DataFrame df = pd.DataFrame({ 'index': [0,1,2,3,4,5,6,7], 'Col1': [1,1,1,2,2,3,3,3], 'Col2': ['X','Y','X','X','X','X','X','Y'], 'Col3': ['ABC','XX','QW','VB','AY','MM','YY','XX'] }) def process_group(group): if 'Y' in group['Col2'].values: # 提取分组内Col2=Y对应的Col3值 target_val = group[group['Col2'] == 'Y']['Col3'].iloc[0] # 返回全组填充该值的序列 return pd.Series([target_val]*len(group), index=group.index) else: # 无Y则返回原Col3值 return group['Col3'] # 生成New_Col df['New_Col'] = df.groupby('Col1').apply(process_group).droplevel(0) print(df)
方法二:简洁版(利用映射填充)
先提取所有含Y分组的对应Col3值,再通过分组transform匹配,最后填充缺省值:
import pandas as pd df = pd.DataFrame({ 'index': [0,1,2,3,4,5,6,7], 'Col1': [1,1,1,2,2,3,3,3], 'Col2': ['X','Y','X','X','X','X','X','Y'], 'Col3': ['ABC','XX','QW','VB','AY','MM','YY','XX'] }) # 建立Col1到对应Y值的映射 y_mapping = df[df['Col2'] == 'Y'].set_index('Col1')['Col3'] # 分组后获取映射值,无映射则用原Col3填充 df['New_Col'] = df.groupby('Col1')['Col1'].transform(lambda g: y_mapping.get(g.iloc[0])).fillna(df['Col3']) print(df)
两种方法都能得到符合要求的输出结果。
内容的提问来源于stack exchange,提问作者user3585510
相关产品推荐
相关产品推荐

