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您所说的每个日期的输出天数是什么意思?我修改了有问题的输出。让我们来看看。