如何在Pandas中根据另一列的非重复值创建新列?
问题解决:根据分组规则生成DataFrame新列
x 原始DataFrame
import pandas as pd import numpy as np df = pd.DataFrame( { 'a': [98, 97, 100, 101, 103, 110, 108, 109, 130, 135], 'b': [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], 'c': [np.nan, np.nan, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0], 'd': [92, 92, 92, 92, 92, 92, 92, 92, 92, 92], } )
预期输出
a b c d x 0 98 3 NaN 92 92 1 97 3 NaN 92 92 2 100 3 1.0 92 94 3 101 3 1.0 92 94 4 103 3 1.0 92 94 5 110 3 2.0 92 104 6 108 3 2.0 92 104 7 109 3 2.0 92 104 8 130 3 3.0 92 124 9 135 3 3.0 92 124
生成规则
- 当
c列的值为首次出现的非重复值时,计算x = a - (b * 2),并将该值填充到该c值对应的所有行 - 当
c为NaN时,x直接取d列的值
尝试过的无效代码
df['x'] = df.a - (df.b * 2) df.loc[df.c.isna(), 'x'] = df.d df['x'] = df.x.cummax()
正确实现方法
方法一:分组填充
利用groupby按c分组,保留每组首行的计算值并填充整个组,最后替换NaN行的x值:
# 先计算所有行的基准计算值 df['x'] = df['a'] - (df['b'] * 2) # 按c分组,将每组的x值替换为组内第一个值 df['x'] = df.groupby('c')['x'].transform('first') # 将c为NaN的行的x替换为d列的值 df.loc[df['c'].isna(), 'x'] = df['d']
方法二:标记首行+向前填充
先初始化NaN行的x为d,标记每个c分组的首行并计算对应值,最后向前填充完成同组赋值:
# 初始化x列为d的值,覆盖NaN行的需求 df['x'] = df['d'] # 标记c列非空且与前一行值不同的行(即每个分组的首行) group_start_mask = df['c'].notna() & (df['c'] != df['c'].shift()) # 对分组首行计算x的目标值 df.loc[group_start_mask, 'x'] = df.loc[group_start_mask, 'a'] - (df.loc[group_start_mask, 'b'] * 2) # 向前填充x列,让同组后续行继承首行的x值 df['x'] = df['x'].ffill()
两种方法均可得到符合预期的结果,方法二更贴合规则描述的逻辑。
内容的提问来源于stack exchange,提问作者AmirX
相关产品推荐
相关产品推荐

