按连续天计算组的值
count values of groups by consecutive days
我有包含 3 列的数据:日期、ID、销售额。
我的第一个任务是过滤 100 以上的销售额。我做到了。
第二个任务,按连续天数对 id 进行分组。
index
date
id
sales
0
01/01/2018
03
101
1
01/01/2018
07
178
2
02/01/2018
03
120
3
03/01/2018
03
150
4
05/01/2018
07
205
结果应该是:
index
id
count
0
03
3
1
07
1
2
07
1
我需要在不使用 pandas/dataframe 的情况下完成此任务,但现在我无法想象从哪一方攻击这个问题。
只是为了努力,我在这里尝试了解决方案的建议
但 ids 没有分组。
这是我的代码:
data = df[df['sales'] >= 100]
data['date'] = pd.to_datetime(data['date']).dt.date
s = data.groupby('id').date.diff().dt.days.ne(1).cumsum()
new_frame = data.groupby(['id', s]).size().reset_index(level=0, drop=True)
“new_frame”将有“count”列是非常重要的,因为之后我需要按“count”列中那些计数天数的范围来计算 id。例如ID 的计数在 0-7 天、7-12 天等范围内,但这不是我的问题的一部分。
非常感谢
您的代码很接近,但需要进行一些微调,如下所示:
data = df[df['sales'] >= 100]
data['date'] = pd.to_datetime(data['date'], dayfirst=True)
df2 = data.sort_values(['id', 'date'])
s = df2.groupby('id').date.diff().dt.days.ne(1).cumsum()
new_frame = df2.groupby(['id', s]).size().reset_index(level=1, drop=True).reset_index(name='count')
结果:
print(new_frame)
id count
0 3 3
1 7 1
2 7 1
更改摘要:
由于您的日期在 dd/mm/yyyy
而不是默认的 mm/dd/yyyy
,您必须在 pd.to_datetime()
中指定参数 dayfirst=True
。否则,02/01/2018
将被视为 2018-02-01
而不是预期的 2018-01-02
并且与相邻条目的日期差异将在 30 左右而不是 1.
我们添加了一个排序步骤来按列 id
和 date
进行排序,以简化后面在创建系列 s
.[=30 时的分组=]
在最后一个 groupby()
中,代码 reset_index(level=0, drop=True)
应该改为 level=1
。因为,level=0
是我们要保留的 id
字段。
在最后的 groupby()
中,我们做了一个额外的 .reset_index(name='count')
使 Pandas 系列变回数据框,并将新列命名为 count
.
我有包含 3 列的数据:日期、ID、销售额。 我的第一个任务是过滤 100 以上的销售额。我做到了。 第二个任务,按连续天数对 id 进行分组。
index | date | id | sales |
---|---|---|---|
0 | 01/01/2018 | 03 | 101 |
1 | 01/01/2018 | 07 | 178 |
2 | 02/01/2018 | 03 | 120 |
3 | 03/01/2018 | 03 | 150 |
4 | 05/01/2018 | 07 | 205 |
结果应该是:
index | id | count |
---|---|---|
0 | 03 | 3 |
1 | 07 | 1 |
2 | 07 | 1 |
我需要在不使用 pandas/dataframe 的情况下完成此任务,但现在我无法想象从哪一方攻击这个问题。
只是为了努力,我在这里尝试了解决方案的建议
data = df[df['sales'] >= 100]
data['date'] = pd.to_datetime(data['date']).dt.date
s = data.groupby('id').date.diff().dt.days.ne(1).cumsum()
new_frame = data.groupby(['id', s]).size().reset_index(level=0, drop=True)
“new_frame”将有“count”列是非常重要的,因为之后我需要按“count”列中那些计数天数的范围来计算 id。例如ID 的计数在 0-7 天、7-12 天等范围内,但这不是我的问题的一部分。 非常感谢
您的代码很接近,但需要进行一些微调,如下所示:
data = df[df['sales'] >= 100]
data['date'] = pd.to_datetime(data['date'], dayfirst=True)
df2 = data.sort_values(['id', 'date'])
s = df2.groupby('id').date.diff().dt.days.ne(1).cumsum()
new_frame = df2.groupby(['id', s]).size().reset_index(level=1, drop=True).reset_index(name='count')
结果:
print(new_frame)
id count
0 3 3
1 7 1
2 7 1
更改摘要:
由于您的日期在
dd/mm/yyyy
而不是默认的mm/dd/yyyy
,您必须在pd.to_datetime()
中指定参数dayfirst=True
。否则,02/01/2018
将被视为2018-02-01
而不是预期的2018-01-02
并且与相邻条目的日期差异将在 30 左右而不是 1.我们添加了一个排序步骤来按列
id
和date
进行排序,以简化后面在创建系列s
.[=30 时的分组=]在最后一个
groupby()
中,代码reset_index(level=0, drop=True)
应该改为level=1
。因为,level=0
是我们要保留的id
字段。在最后的
groupby()
中,我们做了一个额外的.reset_index(name='count')
使 Pandas 系列变回数据框,并将新列命名为count
.