【问题标题】:Dataframe - Create new column based on condition数据框 - 根据条件创建新列
【发布时间】:2021-11-04 06:40:36
【问题描述】:

我正在处理一个有几千行和几列的数据框。感兴趣的列称为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

我要做的是在名为 customer_group_csate_score_toggle_statusis_customer_perf_above_group_perf 的数据框中创建 2 个新列。 customer_group_csate_score_toggle_status 仅当 customer_csate_score & group_csate_score cross over & False 当没有交叉时。 is_customer_perf_above_group_perf 是 True 如果 customer_csate_score 高于 group_csate_score & False 如果customer_csate_score 低于 group_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
    )

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

【问题讨论】:

  • 如果您能提供一个带有样本数据和更简单(更短)的变量/列名的最小工作示例,将会有所帮助。

标签: python pandas dataframe numpy


【解决方案1】:

您可以为交叉条件设置布尔掩码。由于有 2 种可能的交叉情况,我们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']

注意:在检查上一行时,我们不需要对第一行进行特殊处理。在比较第一行的(df['customer_csate_score'].shift() &lt; df['group_csate_score'].shift())(df['customer_csate_score'].shift() &gt; df['group_csate_score'].shift()) 时,它将始终返回False,因为我们将NaNNaN 进行比较。因此,比较 (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

【讨论】:

  • 非常感谢@SeaBean。这对我有用。另外,非常感谢 cmets。
【解决方案2】:

您可以先计算“is_customer_perf_above_group_perf”,这是对最初两列的简单比较。然后计算新列上的diff,当值发生变化时(即存在“交叉”时),它将为 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

【讨论】:

  • 非常感谢@mozway。这很好用。
猜你喜欢
  • 2018-07-01
  • 1970-01-01
  • 2020-10-02
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
  • 2021-07-21
相关资源
最近更新 更多