【问题标题】:Cumulative sales data with threshold value forming a new series / column with a boolean value?具有阈值的累积销售数据形成具有布尔值的新系列/列?
【发布时间】:2021-07-13 11:49:41
【问题描述】:

我有这种类型的数据,但在现实生活中它有数百万个条目。产品 ID 始终是特定于产品的,但在其生命周期内会出现多次。

date product id revenue estimated lifetime value
2021-04-16 0061M00001AXc5lQAD 970 2000
2021-04-17 0061M00001AXbCiQAL 159 50000
2021-04-18 0061M00001AXb9AQAT 80 3000
2021-04-19 0061M00001AXbIHQA1 1100 8000
2021-04-20 0061M00001AXbY8QAL 90 4000
2021-04-21 0061M00001AXbQ1QAL 29 30000
2021-04-21 0061M00001AXc5lQAD 30 2000
2021-05-02 0061M00001AXc5lQAD 50 2000
2021-05-05 0061M00001AXc5lQAD 50 2000

我希望在 pandas 中创建一个新列,以指示某个产品 ID 产生的收入何时超过特定阈值,例如100 美元、1000 美元,将其标记为赢 (1)。在产品的生命周期中,一次胜利可能只会发生一次。此外,我想创建另一列来指示特定产品销售额超过的行,例如估计生命周期价值的 10%。

在 Python / Pandas 中实现这一目标最直观的方法是什么?

编辑:

  • dw1k_thresh:如果特定产品 id 的累计销售额 >= 1000,则该列取布尔值 1,否则为零。然而,1 只能出现一次,之后又总是为零。基本上它只是一个产品销售超过临界值1000的日期和交易的指标。

  • dw10perc:如果一个产品 id 的累计销售额 >= 估计生命周期价值的 10%,则该列取值为 1,否则为 0。但是 1 只能出现一次,之后始终为零。基本上它只是产品销售超过估计生命周期价值10%的临界值时的日期和交易指标。

  • 阈值对于所有产品 ID 都是通用的(我将在稍后阶段使用不同的阈值复制该过程,以确定预测未来收入的最佳阈值)。

我正在努力实现这一目标:

目前我写的代码是试图建立 cum_rev 和 dw1k_thresh 列,但不幸的是它不起作用。

df_final["dw1k_thresh"] = 0
df_final["cum_rev"]= 0 

opp_list =set()

for row in df_final["product id"].iteritems():
    opp_list.add(row)


opp_list=list(opp_list)
opp_list=pd.Series(opp_list)


for i in opp_list: 
    if i == df_final["product id"].any():
        df_final.cum_rev = df_final.revenue.cumsum()

    for x in df_final.cum_rev:
        if x >= 1000 & df_final.dw1k_thresh.sum() == 0: 
            df_final.dw1k_thresh = 1
        else: 
            df_final.dw1k_thresh = 0

df_final.head(30)

【问题讨论】:

  • 阈值是所有产品通用的还是会根据product_id变化?
  • 我已在问题中添加信息并回答了您的问题,因此阈值适用于所有产品。

标签: python python-3.x pandas


【解决方案1】:
  1. 累计收入:可以使用groupbycumsum 相当简单地计算。
  2. dwk1k_thresh:我们首先检查 cum_rev 是否​​大于 1000,然后应用帮助我们保持 1仅一次的函数,然后再次始终为零。
  3. dw10_perc:方法与 dw1k_thresh 相同。

作为第一步,您需要删除 $ 并确保您的列是数字类型以执行您概述的比较。

# Imports
import pandas as pd
import numpy as np

# Remove $ sign and convert to numeric
cols = ['revenue','estimated lifetime value']
df[cols] = df[cols].replace({'\$': '', ',': ''}, regex=True).astype(float)

# Cumulative Revenue
df['cum_rev'] = df.groupby('product id')['revenue'].cumsum()

# Function to be applied on both
def f(df,thresh_col):
    return  (df[df[thresh_col]==1].sort_values(['date','product id'], ascending=False)
            .groupby('product id', as_index=False,group_keys=False)
            .apply(lambda x: x.tail(1))
            ).index.tolist()

# dw1k_thresh
df['dw1k_thresh'] = np.where(df['cum_rev'].ge(1000),1,0)
df['dw1k_thresh'] = np.where(df.index.isin(f(df,'dw1k_thresh')),1,0)

# dw10perc
df['dw10_perc'] = np.where(df['cum_rev'] > 0.10 * df.groupby('product id',observed=True)['estimated lifetime value'].transform('sum'),1,0)
df['dw10_perc'] = np.where(df.index.isin(f(df,'dw10_perc')),1,0)

打印:

>>> df

        date          product id  revenue  ...  cum_rev  dw1k_thresh  dw10_perc
0 2021-04-16  0061M00001AXc5lQAD      970  ...      970            0          1
1 2021-04-17  0061M00001AXbCiQAL      159  ...      159            0          0
2 2021-04-18  0061M00001AXb9AQAT       80  ...       80            0          0
3 2021-04-19  0061M00001AXbIHQA1     1100  ...     1100            1          1
4 2021-04-20  0061M00001AXbY8QAL       90  ...       90            0          0
5 2021-04-21  0061M00001AXbQ1QAL       29  ...       29            0          0
6 2021-04-21  0061M00001AXc5lQAD       30  ...     1000            1          0
7 2021-05-02  0061M00001AXc5lQAD       50  ...     1050            0          0
8 2021-05-05  0061M00001AXc5lQAD       50  ...     1100            0          0

【讨论】:

  • 谢谢,太好了!还有一件事,似乎代码也及时向前看。我希望它只包含直到特定行的日期,并基于该日期创建历史上特定时刻的快照。
  • dw1k_thresh:如果特定产品 id 的累计销售额 >= 1000,则该列取布尔值 1,否则为零。然而,1 只能出现一次,之后又总是为零。基本上它只是一个产品销售超过临界值1000的日期和交易的指标。
  • dw10perc:如果一个产品 id 的累计销售额 >= 估计生命周期价值的 10%,则该列的值为 1,否则为 0。但是 1 只能出现一次,之后始终为零.基本上,它只是产品销售超过估计生命周期价值 10% 的临界值时的日期和交易指标。
  • 谢谢@ShubhamSharma。我很感激。我认为部分答案可以改进,我会尝试改进它,我只是不想让 OP 等待更长时间并给出一个半准备好的答案:)。再次感谢
  • @sophcles 非常感谢!!!如果没有你的帮助,我永远不会想出解决方案!
猜你喜欢
  • 2021-04-05
  • 2019-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-14
  • 2013-08-29
相关资源
最近更新 更多