Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python计算日期之间的平均天数_Python_Pandas_If Statement_Group By_Average - Fatal编程技术网

Python计算日期之间的平均天数

Python计算日期之间的平均天数,python,pandas,if-statement,group-by,average,Python,Pandas,If Statement,Group By,Average,使用以下python数据帧df: Customer_ID | Transaction_ID ABC 2016-05-06-1234 ABC 2017-06-08-3456 ABC 2017-07-12-5678 ABC 2017-12-20-6789 BCD 2016-08-23-7891 BCD 2016-09-21-2345 BCD 201

使用以下python数据帧df:

Customer_ID | Transaction_ID
ABC            2016-05-06-1234
ABC            2017-06-08-3456
ABC            2017-07-12-5678
ABC            2017-12-20-6789
BCD            2016-08-23-7891
BCD            2016-09-21-2345
BCD            2017-10-23-4567
不幸的是,日期隐藏在事务id字符串中。我以这种方式编辑了数据帧

#year of transaction
df['year'] = df['Transaction_ID'].astype(str).str[:4]

#date of transaction
df['date'] = df['Transaction_ID'].astype(str).str[:10]

#format date
df['date']=pd.to_datetime(df['date'], format='%Y-%m-%d')

#calculate visit number per year
df['visit_nr_yr'] = df.groupby(['Customer_ID', 'year']).cumcount()+1
现在df看起来像这样:

Customer_ID | Transaction_ID    | year  | date        |visit_nr_yr 
ABC            2016-05-06-1234    2016    2016-05-06    1            
ABC            2017-06-08-3456    2017    2017-06-08    1            
ABC            2017-07-12-5678    2017    2017-07-12    2            
ABC            2017-12-20-6789    2017    2017-12-20    3            
BCD            2016-08-23-7891    2016    2016-08-23    1            
BCD            2016-09-21-2345    2016    2016-09-21    2            
BCD            2017-10-23-4567    2017    2017-10-23    1            
我需要计算以下各项:

  • 每次访问的平均间隔天数是多少(因此介于1和2之间以及介于2和3之间)
  • 一般来说,两次访问之间的平均天数是多少
首先,我想包括以下专栏“每年访问之间的天数”(由客户ID计算):

请注意,我故意避免0,并保留NaN,以防有人在同一天进行两次访问

接下来,我想计算每次访问之间的平均天数(一年内介于1和2之间以及介于2和3之间)。正在查找此输出:

avg_days_bw_visits_1_2 | avg_days_bw_visits_2_3
31.5                     161
最后,我想计算访问之间的平均天数:

output: 203.8 
#the days between visits are 398,34,161,29,397 and the average of those 
 numbers is 203.8
我一直在研究如何创建“days\u bw\u Visites\u yr”专栏。
南必须被排除在数学之外

通过将“日期”列下移1,您可以获得以前的就诊日期(按客户和年份分组):

df['previous_visit'] = df.groupby(['Customer_ID', 'year'])['date'].shift()
从这一点来看,两次访问之间的天数仅仅是区别:

df['days_bw_visits'] = df['date'] - df['previous_visit']
要计算平均值,请将日期增量对象转换为天:

df['days_bw_visits'] = df['days_bw_visits'].apply(lambda x: x.days)
访问间隔的平均天数:

df.groupby('visit_nr_yr')['days_bw_visits'].agg('mean')

df['days_bw_visits'].mean()
资料来源:

In [96]: df
Out[96]:
  Customer_ID   Transaction_ID
0         ABC  2016-05-06-1234
1         ABC  2017-06-08-3456
2         ABC  2017-07-12-5678
3         ABC  2017-12-20-6789
4         BCD  2016-08-23-7891
5         BCD  2016-09-21-2345
6         BCD  2017-10-23-4567
解决方案:

df['Date'] = pd.to_datetime(df.Transaction_ID.str[:10])
df['visit_nr_yr'] = df.groupby(['Customer_ID', df['Date'].dt.year]).cumcount()+1
df['days_bw_visits_yr'] = \
    df.groupby(['Customer_ID', df['Date'].dt.year])['Date'].diff().dt.days
结果:

In [98]: df
Out[98]:
  Customer_ID   Transaction_ID       Date  visit_nr_yr  days_bw_visits_yr
0         ABC  2016-05-06-1234 2016-05-06            1                NaN
1         ABC  2017-06-08-3456 2017-06-08            1                NaN
2         ABC  2017-07-12-5678 2017-07-12            2               34.0
3         ABC  2017-12-20-6789 2017-12-20            3              161.0
4         BCD  2016-08-23-7891 2016-08-23            1                NaN
5         BCD  2016-09-21-2345 2016-09-21            2               29.0
6         BCD  2017-10-23-4567 2017-10-23            1                NaN

值得注意的是,除了获得上次购买之间的时间差

df['previous_visit'] = df.groupby(['Customer_ID', 'year'])['date'].shift()
df['days_bw_visits'] = df['date'] - df['previous_visit'] 
df['days_bw_visits'] = df['days_bw_visits'].apply(lambda x: x.days)
在执行.shift()之前,您应该确保您的日期按组值排序,以避免负面的天数访问

df = df.sort_values(['Customer_ID', 'DATE_D'])

你能发布你想要的(结束)数据集吗?@MaxU,带有days\u bw\u visions\u yr列的数据框是想要的结束数据集-然后在该数据集上完成另外两个计算,但不会添加到数据框中,因为它们是聚合平均值;非常感谢-现在就测试这个解决方案;shift选项听起来像格雷蒂,但不幸地得到了“Dataerror:error message No numeric types to aggregate”(数据错误:错误消息No numeric types to aggregate)我认为这与日期不是日期类型有关?对于任何将此视为解决方案的人来说。请确保在执行
shift()
之前对日期列进行排序。因此,第一行代码应该是
df=df.sort\u值(by='date)
然后继续使用parasu的代码。我刚刚花了30分钟试图找出代码的错误。我的df已经排序了99%,除了几行导致了一些奇怪的负值。谢谢@MaxU;我完全按照您的步骤进行操作,但是在最后几天的访问中,我得到了这个错误属性error:只能使用.dt具有datetimelike值的访问器
df = df.sort_values(['Customer_ID', 'DATE_D'])