python - 查找客户在 pandas 中活跃的最大连续月份数

标签 python python-3.x pandas dataframe pandas-groupby

我正在尝试查找客户在商店中活跃的最大连续月份数。这是我拥有的数据。

+-----+---------+--------------+--------+-------------+
| Id  | t_year  | t_month_prx  | Store  | diff_months |
+-----+---------+--------------+--------+-------------+
|  1  |   2021  |        10.0  | A001   |         1.0 |
|  1  |   2022  |         1.0  | A001   |         1.0 |
|  1  |   2022  |         2.0  | A001   |         1.0 |
|  2  |   2021  |         1.0  | A001   |         1.0 |
|  2  |   2021  |         2.0  | A001   |         1.0 |
|  2  |   2021  |         3.0  | A001   |         1.0 |
|  2  |   2021  |         6.0  | A001   |         3.0 |
|  2  |   2021  |         7.0  | A001   |         1.0 |
|  2  |   2021  |         8.0  | A001   |         1.0 |
|  2  |   2021  |         9.0  | A001   |         1.0 |
|  2  |   2021  |        10.0  | A001   |         1.0 |
|  2  |   2022  |         1.0  | A001   |         1.0 |
|  2  |   2022  |         2.0  | A001   |         1.0 |
|  2  |   2021  |         1.0  | A002   |         1.0 |
|  2  |   2021  |         2.0  | A002   |         1.0 |
|  2  |   2021  |         3.0  | A002   |         1.0 |
|  2  |   2021  |         6.0  | A002   |         3.0 |
|  2  |   2021  |         7.0  | A002   |         1.0 |
|  2  |   2021  |         8.0  | A002   |         1.0 |
|  2  |   2021  |         9.0  | A002   |         1.0 |
|  2  |   2021  |        10.0  | A002   |         1.0 |
|  3  |   2021  |        10.0  | A002   |         1.0 |
|  3  |   2022  |         1.0  | A002   |         1.0 |
|  3  |   2022  |         2.0  | A002   |         1.0 |
+-----+---------+--------------+--------+-------------+

最初的问题涉及跳过两个月,所以我做了一个月的代理。因此,一年不是 12 个月,而是 10 个月。

到目前为止我尝试过的是:

df = df.sort_values(by=['Id','t_year','t_month_prx'], ascending = True).reset_index(drop=True)
df['diff_months'] = df.groupby(['Id', 't_year'])['t_month_prx'].diff()
df['diff_months'].fillna(method='bfill', inplace=True)

我得到了这个结果

df_result = pd.DataFrame({
'Id': {0: 1,1: 1,2: 1,3: 2,4: 2,5: 2,6: 2,7: 2, 8: 2,9: 2, 10: 2, 11: 2, 12: 2},
't_year': {0: 2021, 1: 2022, 2: 2022, 3: 2021,4: 2021,5: 2021,6: 2021,7: 2021,8: 2021,9: 2021,10: 2021,11: 2022,12: 2022},
 't_month_prx': {0: 10.0,1: 1.0,2: 2.0,3: 1.0,4: 2.0,5: 3.0,6: 6.0,7: 7.0,
 8: 8.0,9: 9.0,10: 10.0,11: 1.0,12: 2.0},
'diff_months': {0: 1.0, 1: 1.0, 2: 1.0,3: 1.0,4: 1.0,5: 1.0,6: 3.0,7: 1.0,8: 1.0,9: 1.0,10: 1.0,11: 1.0, 12: 1.0}
})

最后我厌倦了计算所有连续的1

df.groupby([df['Id'], df['diff_months'].ne(df.groupby('Id')['diff_months'].shift(1)).cumsum()])['diff_months'].sum().groupby(level=0).max().reset_index(name='consecutive_month')

它给了我以下结果

pd.DataFrame({
'Id': {0: 1,1: 2},
'counts': {0: 3.0,1: 6.0}
})

但期望的输出是:

pd.DataFrame({'Id': [1,2, 2, 3], 'Store': ['A001','A001', 'A002', 'A002'], 'counts': [3, 7, 5, 3]})

看起来像:

   Id Store  counts
0   1  A001       3
1   2  A001       7
2   2  A002       5
3   3  A002       3

因此,对于第二个客户来说,应该是 7 个月,因为我只计算 1s,所以跳过了 3。类似地,可以有多个较小的 1 序列,在这种情况下,必须选择 1 的最大计数。我的方法好不好?知道如何计算可以跨越不同年份的连续月份吗?

最佳答案

您可以首先使用 groupby + diff 创建组(在任何给定年份,要“连续”,差值必须为 1;跨年,它有为-9)。然后使用另一个groupby + size中的组来查找连续计数;然后再执行一次 groupby + max 来查找每个 Id 的最大连续计数。

cols = ['Id', 'Store']
g = df.groupby(cols)
month_diff = g['t_month_prx'].diff()
year_diff = g['t_year'].diff()
nonconsecutive = ~((year_diff.eq(0) & month_diff.eq(1)) | (year_diff.eq(1) & month_diff.eq(-9)))
out = df.groupby([*cols, nonconsecutive.cumsum()]).size().droplevel(-1).groupby(cols).max().reset_index(name='counts')

输出:

   Id Store  counts
0   1  A001       3
1   2  A001       7
2   2  A002       5
3   3  A002       3

关于python - 查找客户在 pandas 中活跃的最大连续月份数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71522919/

相关文章:

python-3.x - Django 无法创建到 'postgres' 数据库的连接,将使用默认数据库代替

python - Pandas - 根据其他行中的相对值计算新列

python - 如何在 Pandas 中标记具有多个条件的列?

python-3.x - 为什么我的蛮力(O((n1 + n2)log(n1 + n2)))解决方案比优化解决方案(O(n1 + n2))更快?

python - 为什么我的代码不起作用?在比赛前找到一个词

python - 如何将字符串拆分为单词和空格?

python - 跨函数调用维护生成器对象

python - 从数据框中绘制并排堆叠条形图

python - 直方图的颜色和标签不一致

python - 根据组切片数据帧,没有连续的字符串