我正在处理一个数据帧,它有几千行&有几列。感兴趣的列称为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_perf
。customer_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())
的第一行时,因为我们比较NaN
和NaN
。因此比较(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