动态日期差异计算熊猫

时间:2019-12-25 14:12:19

标签: python pandas

 customer_id    Order_date 
        1       2015-01-16      
        1       2015-01-19      
        2       2014-12-21      
        2       2015-01-10      
        1       2015-01-10
        3       2018-01-18
        3       2017-03-04
        4       2019-11-05
        4       2010-01-01
        3       2019-02-03      

让我们说我有这样的数据

对于一家电子商务公司来说,有些人定期购买,有些人每年购买一次,有些人每月购买一次,等等。我需要找出每个客户的每笔交易频率之间的差异。

这将是一个动态列表,因为有些人已经完成了数千次交易,有些人已经进行了一次,十次等等。有关如何实现此目标的任何想法。

所需的输出:

   customer_id  Order_date_Difference_in_days 
        1       6,3  #Difference b/w first 2 dates 2015-01-10 and 2015-01-16 
                     #is 6 days and diff b/w next 2 consecutive dates is                                                   
                     #2015-01-16 and 2015-01-19 is #3 days   
        2       20      
        3       320,381
        4       3596

基本上,这是为每个客户ID首先对日期进行排序后的日期之间的差异

2 个答案:

答案 0 :(得分:4)

您也可以将以下内容用于当前输出:

m=(df.assign(Diff=df.sort_values(['customer_id','Order_date'])
    .groupby('customer_id')['Order_date'].diff().dt.days).dropna())

m=m.assign(Diff=m['Diff'].astype(str)).groupby('customer_id')['Diff'].agg(','.join)

customer_id
1        6.0,3.0
2           20.0
3    320.0,381.0
4         3595.0
Name: Diff, dtype: object

答案 1 :(得分:3)

首先,我们需要按客户ID和订单日期对数据进行排序

确保您的日期时间是正确的日期时间呼叫df['Order_date'] = pd.to_datetime(df['Order_date'])

df.sort_values(['customer_id','Order_date'],inplace=True)

df["days"] = df.groupby("customer_id")["Order_date"].apply(
    lambda x: (x - x.shift()) / np.timedelta64(1, "D")
)

print(df)
  customer_id Order_date    days
4            1 2015-01-10     NaN
0            1 2015-01-16     6.0
1            1 2015-01-19     3.0
2            2 2014-12-21     NaN
3            2 2015-01-10    20.0
6            3 2017-03-04     NaN
5            3 2018-01-18   320.0
9            3 2019-02-03   381.0
8            4 2010-01-01     NaN
7            4 2019-11-05  3595.0

然后您可以执行简单的agg运算,但需要将值转换为字符串。

df.dropna().groupby("customer_id")["days"].agg(
    lambda x: ",".join(x.astype(str))
).to_frame()
                    days
customer_id             
1                6.0,3.0
2                   20.0
3            320.0,381.0
4                 3595.0