Python 如何按日期分组并查找连续天数计数

Python 如何按日期分组并查找连续天数计数,python,pandas,numpy,dataframe,Python,Pandas,Numpy,Dataframe,所以我有一张像这样的桌子 product date_purchased apple 2018-08-01 apple 2018-08-02 apple 2018-08-03 apple 2018-08-10 apple 2018-08-11 banana 2018-08-14 我试图寻找连续几天购买该产品的次数。像 apple 2018-08-01 1 apple 2018-08-02 2 apple 2018-08-03 3 apple 2018-

所以我有一张像这样的桌子

product date_purchased
apple   2018-08-01
apple   2018-08-02
apple   2018-08-03
apple   2018-08-10
apple   2018-08-11
banana  2018-08-14
我试图寻找连续几天购买该产品的次数。像

apple   2018-08-01  1
apple   2018-08-02  2
apple   2018-08-03  3
apple   2018-08-10  1
apple   2018-08-11  2
banana  2018-08-14  1
产品中的第一列,第二列是最后购买日期,第三列是连续购买的日期


[编辑]:更改了输出格式使用
diff
cumsum
创建一个新键,然后我们可以
groupby
agg

df.date_purchased=pd.to_datetime(df.date_purchased)
df['Newkey']=df.date_purchased.diff().dt.days.ne(1).cumsum()
df
Out[358]: 
  product date_purchased  Newkey
0   apple     2018-08-01       1
1   apple     2018-08-02       1
2   apple     2018-08-03       1
3   apple     2018-08-10       2
4   apple     2018-08-11       2
5  banana     2018-08-14       3
df.groupby(['product','Newkey'])['date_purchased'].agg(['last','count'])
Out[359]: 
                     last  count
product Newkey                  
apple   1      2018-08-03      3
        2      2018-08-11      2
banana  3      2018-08-14      1
更新

df.date_purchased=pd.to_datetime(df.date_purchased)
df['Newkey']=df.date_purchased.diff().dt.days.ne(1).cumsum()
df
Out[384]: 
  product date_purchased  Newkey
0   apple     2018-08-01       1
1   apple     2018-08-02       1
2   apple     2018-08-03       1
3   apple     2018-08-10       2
4   apple     2018-08-11       2
5  banana     2018-08-14       3
df.groupby(['Newkey']).cumcount()+1
Out[385]: 
0    1
1    2
2    3
3    1
4    2
5    1
dtype: int64

使用
diff
cumsum
创建一个新键,然后我们可以
groupby
agg

df.date_purchased=pd.to_datetime(df.date_purchased)
df['Newkey']=df.date_purchased.diff().dt.days.ne(1).cumsum()
df
Out[358]: 
  product date_purchased  Newkey
0   apple     2018-08-01       1
1   apple     2018-08-02       1
2   apple     2018-08-03       1
3   apple     2018-08-10       2
4   apple     2018-08-11       2
5  banana     2018-08-14       3
df.groupby(['product','Newkey'])['date_purchased'].agg(['last','count'])
Out[359]: 
                     last  count
product Newkey                  
apple   1      2018-08-03      3
        2      2018-08-11      2
banana  3      2018-08-14      1
更新

df.date_purchased=pd.to_datetime(df.date_purchased)
df['Newkey']=df.date_purchased.diff().dt.days.ne(1).cumsum()
df
Out[384]: 
  product date_purchased  Newkey
0   apple     2018-08-01       1
1   apple     2018-08-02       1
2   apple     2018-08-03       1
3   apple     2018-08-10       2
4   apple     2018-08-11       2
5  banana     2018-08-14       3
df.groupby(['Newkey']).cumcount()+1
Out[385]: 
0    1
1    2
2    3
3    1
4    2
5    1
dtype: int64

查找日期何时更改,并使用
shift
cumsum
功能创建
date\u组。然后,您可以使用pandas提供的多个聚合功能,按
产品
日期分组

最后,格式化和重命名列以匹配预期输出:

import datetime as dt

(df.assign(date_group=lambda x: (x.date_purchased != x.date_purchased.shift(1)
                                  + dt.timedelta(days=1)).cumsum()
           )
 .groupby(['product', 'date_group'])['date_purchased'].agg(['last', 'count'])
 .reset_index(level=-1, drop=True)
 .rename(columns={'last': 'last_date_purchased',
                 'count': 'times_in_a_row'})
)


         last_date_purchased  times_in_a_row
product                                    
apple            2018-08-03               3
apple            2018-08-11               2
banana           2018-08-14               1
编辑:

所需的输出稍微改变了要遵循的策略。前一个更简单,我为过度使用
lambda
函数而道歉。我确信可以使用一些
管道

代码的变化是这样的,即现在我们不计算每个
组中的元素日期
,而是计算与每天相关联的单个
。我们还必须简单地
groupby
来利用
transform
函数

(df.assign(date_group=lambda x: (x.date_purchased != x.date_purchased.shift(1)
                              + dt.timedelta(days=1)).cumsum(),
        key=1,
        times_in_a_row=lambda x: x.groupby(['product', 'date_group'])
                                  .transform(lambda x: x.cumsum())
       )
[['product', 'date_purchased', 'times_in_a_row']]
)

  product date_purchased  times_in_a_row
0   apple     2018-08-01               1
1   apple     2018-08-02               2
2   apple     2018-08-03               3
3   apple     2018-08-10               1
4   apple     2018-08-11               2
5  banana     2018-08-14               1

查找日期何时更改,并使用
shift
cumsum
功能创建
date\u组。然后,您可以使用pandas提供的多个聚合功能,按
产品
日期分组

最后,格式化和重命名列以匹配预期输出:

import datetime as dt

(df.assign(date_group=lambda x: (x.date_purchased != x.date_purchased.shift(1)
                                  + dt.timedelta(days=1)).cumsum()
           )
 .groupby(['product', 'date_group'])['date_purchased'].agg(['last', 'count'])
 .reset_index(level=-1, drop=True)
 .rename(columns={'last': 'last_date_purchased',
                 'count': 'times_in_a_row'})
)


         last_date_purchased  times_in_a_row
product                                    
apple            2018-08-03               3
apple            2018-08-11               2
banana           2018-08-14               1
编辑:

所需的输出稍微改变了要遵循的策略。前一个更简单,我为过度使用
lambda
函数而道歉。我确信可以使用一些
管道

代码的变化是这样的,即现在我们不计算每个
组中的元素日期
,而是计算与每天相关联的单个
。我们还必须简单地
groupby
来利用
transform
函数

(df.assign(date_group=lambda x: (x.date_purchased != x.date_purchased.shift(1)
                              + dt.timedelta(days=1)).cumsum(),
        key=1,
        times_in_a_row=lambda x: x.groupby(['product', 'date_group'])
                                  .transform(lambda x: x.cumsum())
       )
[['product', 'date_purchased', 'times_in_a_row']]
)

  product date_purchased  times_in_a_row
0   apple     2018-08-01               1
1   apple     2018-08-02               2
2   apple     2018-08-03               3
3   apple     2018-08-10               1
4   apple     2018-08-11               2
5  banana     2018-08-14               1


到目前为止您尝试了什么?我熟悉group by,但我不确定如何连续检查几天并进行计数。仅供参考,最好将您的专栏命名为
products
,因为
product
product
方法冲突。到目前为止您尝试了什么?我熟悉group by,但我不知道如何检查连续几天并进行计数。仅供参考,最好将您的专栏命名为
products
,因为
product
product
方法冲突。只需确保按
产品
购买日期
对数据框进行排序,否则
diff
可能无法工作。太棒了!!。我如何编辑它以显示每个日期的输出天数。@JohnConstantine您指的输出天数是什么?@Wen抱歉,我修改了问题中的输出。太棒了。只需确保按
产品
购买日期
对数据框进行排序,否则
diff
可能无法工作。太棒了!!。如何编辑此文件以显示每个日期的输出天数。@JohnConstantine您指的输出天数是什么?@Wen抱歉,我修改了问题中的输出。太棒了!!。如何编辑此文件以显示每个日期的输出天数。非常抱歉,我忘记添加导入。让我来编辑。@JohnConstantine你说的每个日期的输出天数是什么意思?我修改了有问题的输出。让我们来。太棒了!!。如何编辑此文件以显示每个日期的输出天数。非常抱歉,我忘记添加导入。让我来编辑。@JohnConstantine您所说的每个日期的输出天数是什么意思?我修改了有问题的输出。让我们来看看。