Dataframe -根据条件创建新列



我正在处理一个数据帧,它有几千行&有几列。感兴趣的列称为customer_csate_score&group_csate_score

数据如下

customer_csate_score group_csate_score
0.000                   -0.15
-0.4                     0.12
0                        0.13 
0.578                    0.81   
0.418                    0.96
-0.765                   0.1
0.89                     -0.87

我要做的是在数据框中创建2个新列,称为customer_group_csate_score_toggle_status&is_customer_perf_above_group_perfcustomer_group_csate_score_toggle_status只有在customer_csate_score&group_csate_score交叉&当没有交叉时为False。如果customer_csate_score在上面,则is_customer_perf_above_group_perf为Truegroup_csate_score,如果customer_csate_score低于则为Falsegroup_csate_score

切换状态列的期望输出

customer_group_csate_score_toggle_status  is_customer_perf_above_group_perf
False                                        True
True                                         False
False                                        False
False                                        False
False                                        False
False                                        False
True                                         True

我已经试过这个代码了-

def check_cust_group_crossover(df, df_key1, def_key2):
return np.where(
(
(df[df_key1] > df[def_key2]) & 
(df[df_key1].shift() < df[def_key2].shift())
),
True, False
)

我正在努力实现整个功能。我可以请求指导来实施这个吗?

可以为交叉条件设置布尔掩码。由于有两种可能的交叉情况,我们对它们进行or以得到customer_group_csate_score_toggle_status

的最终条件。对于is_customer_perf_above_group_perf,只需比较customer_csate_score>group_csate_score:

m1 = (df['customer_csate_score'] > df['group_csate_score']) & (df['customer_csate_score'].shift() < df['group_csate_score'].shift())  
m2 = (df['customer_csate_score'] < df['group_csate_score']) & (df['customer_csate_score'].shift() > df['group_csate_score'].shift())  
df['customer_group_csate_score_toggle_status'] = m1 | m2
df['is_customer_perf_above_group_perf'] = df['customer_csate_score'] > df['group_csate_score']
注意:我们不需要对第一行进行特殊处理为检查前一行时的掩码。它总是返回False当比较(df['customer_csate_score'].shift() < df['group_csate_score'].shift())(df['customer_csate_score'].shift() > df['group_csate_score'].shift())的第一行时,因为我们比较NaNNaN。因此比较(NaN>NaN<NaN)总是返回False

。> 结果:

print(df)
customer_csate_score  group_csate_score  customer_group_csate_score_toggle_status  is_customer_perf_above_group_perf
0                 0.000              -0.15                                     False                               True
1                -0.400               0.12                                      True                              False
2                 0.000               0.13                                     False                              False
3                 0.578               0.81                                     False                              False
4                 0.418               0.96                                     False                              False
5                -0.765               0.10                                     False                              False
6                 0.890              -0.87                                      True                               True

可以首先计算"is_customer_perf_above_group_perf",这是对初始两列的简单比较。然后计算新列上的diff,当值改变时(即有"交叉"时),CC_28将为True。这个fillna(False)是设置第一个值,因为它没有前面的行可以比较。

(df.eval('is_customer_perf_above_group_perf = customer_csate_score > group_csate_score')
.assign(customer_group_csate_score_toggle_status=lambda d: d['is_customer_perf_above_group_perf'].diff().fillna(False))
)

输出:

customer_csate_score  group_csate_score  is_customer_perf_above_group_perf  customer_group_csate_score_toggle_status
0                 0.000              -0.15                               True                                     False
1                -0.400               0.12                              False                                      True
2                 0.000               0.13                              False                                     False
3                 0.578               0.81                              False                                     False
4                 0.418               0.96                              False                                     False
5                -0.765               0.10                              False                                     False
6                 0.890              -0.87                               True                                      True