在Pyspark中有没有一种简单的方法来找出将某人转换为客户所需的促销次数?

8yoxcaq7  于 2023-02-07  发布在  Spark
关注(0)|答案(3)|浏览(134)

我有一个日期级别的促销数据框,看起来像这样:
| 识别号|日期|晋升|转换为客户|
| - ------|- ------|- ------|- ------|
| 1个|1月2日|第二章|无|
| 1个|1月10日|三个|1个|
| 1个|1月14日|三个|无|
| 第二章|1月10日|十九|1个|
| 第二章|1月10日|八个|无|
| 第二章|1月10日|十二|无|
现在,我想看看将某人转换为客户所需的促销次数。例如,将ID 1转换为客户所需的促销次数为(2 + 3),将ID 2转换为客户所需的促销次数为(19)。
例如:
| 识别号|日期|
| - ------|- ------|
| 1个|五个|
| 第二章|十九|
我想不出解决这个问题的办法,你能帮帮我吗?
@Corralian和mozway已经用Python帮助解决了这个问题,但是我无法在Pyspark中实现它,因为 Dataframe 太大了(〉1TB)。

50few1ms

50few1ms1#

您可以用途:

prom = (df.groupby('ID')['Promotions'].cumsum()
          .where(df['Converted to customer'].eq(1))
          .dropna().astype(int))

out = df.loc[prom.index, ['ID', 'Date']].assign(Promotion=prom)
print(out)

# Output
   ID     Date  Promotion
1   1  10-Jan           5
3   2  10-Jan          19
5uzkadbs

5uzkadbs2#

使用一个groupby生成掩码以隐藏行,然后使用一个groupby.sum生成总和:

mask = (df.groupby('ID', group_keys=False)['Converted to customer']
          .apply(lambda s: s.eq(1).shift(fill_value=False).cummax())
       )

out = df[~mask].groupby('ID')['Promotions'].sum()

输出:

ID
1     5
2    19
Name: Promotions, dtype: int64

备选输出:

df[~mask].groupby('ID', as_index=False).agg(**{'Number': ('Promotions', 'sum')})

输出:

ID  Number
0   1       5
1   2      19

如果您可能具有未转换为客户的组,则可能还需要聚合""列作为指示符:

mask = (df.groupby('ID', group_keys=False)['Converted to customer']
          .apply(lambda s: s.eq(1).shift(fill_value=False).cummax())
       )

out = (df[~mask]
       .groupby('ID', as_index=False)
       .agg(**{'Number': ('Promotions', 'sum'),
               'Converted': ('Converted to customer', 'max')
              })
      )

输出:

ID  Number  Converted
0   1       5          1
1   2      19          1
2   3      39          0

替代输入:

ID    Date  Promotions  Converted to customer
0   1   2-Jan           2                      0
1   1  10-Jan           3                      1
2   1  14-Jan           3                      0
3   2  10-Jan          19                      1
4   2  10-Jan           8                      0
5   2  10-Jan          12                      0
6   3  10-Jan          19                      0 # this group has
7   3  10-Jan           8                      0 # no conversion
8   3  10-Jan          12                      0 # to customer
6ojccjat

6ojccjat3#

您希望按ID进行计算,因此groupby ID似乎比较合适,例如

data.groupby("ID").apply(fct)

现在编写一个单独的函数agg_fct,它计算只包含一个ID的 Dataframe 的结果。假设数据按日期排序,我猜

def agg_fct(df):
   index_of_conv = df["Converted to customer"].argmax()
   return df.iloc[0:index_of_conv,df.columns.get_loc("Promotions")].sum()

好的。你可能需要做一些调整,以防客户从未被转换。

相关问题