python中基于ID的两个日期之间的动态行数



我一直在尝试计算动态变化日期之间每个ID的行数。

我的数据集如下:

<表类> 日期 ID Minimum_Date 分钟+ 6 m 分钟+ 12 m 分钟+ 18 m tbody><<tr>2017-07-3112017-07-312018-01-312018-07-312019-01-312018-05-0812017-07-312018-01-312018-07-312019-01-312018-11-1012017-07-312018-01-312018-07-312019-01-31………………2019-07-08132019-07-082020-01-082020-07-082021-01-082019-08-10132019-07-082020-01-082020-07-082021-01-082019-09-19132019-07-082020-01-082020-07-082021-01-082019-12-23132019-07-082020-01-082020-07-082021-01-08

我想你是从DateID列开始的。在这种情况下,在transform:

的帮助下,您可以很容易地构建其他列。
  • groupby.transform可以为您提供正确形状的组最小日期,以便与Date列进行比较
  • 带有dictionary参数的
  • series.transform可以通过每次移动几个月来获得您想要的边界日期的数据帧。这必须在DateOffset中完成。
>>> dates = df.groupby('ID')['Date'].transform('min')
>>> dates
0   2017-07-31
1   2017-07-31
2   2017-07-31
4   2019-07-08
5   2019-07-08
6   2019-07-08
7   2019-07-08
Name: Date, dtype: datetime64[ns]
>>> dates = dates.transform({f'min + {n}m': lambda s, months=n: s + pd.offsets.DateOffset(months=months) for n in [0, 6, 12, 18]})
>>> dates
min + 0m   min + 6m  min + 12m  min + 18m
0 2017-07-31 2018-01-31 2018-07-31 2019-01-31
1 2017-07-31 2018-01-31 2018-07-31 2019-01-31
2 2017-07-31 2018-01-31 2018-07-31 2019-01-31
4 2019-07-08 2020-01-08 2020-07-08 2021-01-08
5 2019-07-08 2020-01-08 2020-07-08 2021-01-08
6 2019-07-08 2020-01-08 2020-07-08 2021-01-08
7 2019-07-08 2020-01-08 2020-07-08 2021-01-08

从那里比较所有这些日期很容易,但需要使用.le().gt()而不是<=>来指定我们比较的维度:

>>> dates.le(df['Date'], axis='index').groupby(df['ID']).sum()
min + 0m  min + 6m  min + 12m  min + 18m
ID                                           
1           3         2          1          0
13          4         0          0          0

这些是累积的,因为ID 1的所有3个日期都计算在min + 0m列中,即使它们也在后面的列中。我们可以用两种方法中的一种来纠正这个错误,或者改变这个累积结果:

>>> cumul = dates.le(df['Date'], axis='index').groupby(df['ID']).sum()
>>> cumul.diff(-1, axis='columns').fillna(cumul).astype(int)
min + 0m  min + 6m  min + 12m  min + 18m
ID                                           
1           1         1          1          0
13          4         0          0          0

另一种方法是比较日期小于一个边界日期但大于下一个边界日期:

>>> dates
min + 0m   min + 6m  min + 12m  min + 18m
0 2017-07-31 2018-01-31 2018-07-31 2019-01-31
1 2017-07-31 2018-01-31 2018-07-31 2019-01-31
2 2017-07-31 2018-01-31 2018-07-31 2019-01-31
4 2019-07-08 2020-01-08 2020-07-08 2021-01-08
5 2019-07-08 2020-01-08 2020-07-08 2021-01-08
6 2019-07-08 2020-01-08 2020-07-08 2021-01-08
7 2019-07-08 2020-01-08 2020-07-08 2021-01-08
>>> next_date = dates.shift(-1, axis='columns', fill_value=pd.Timestamp.max)
>>> next_date
min + 0m   min + 6m  min + 12m                     min + 18m
0 2018-01-31 2018-07-31 2019-01-31 2262-04-11 23:47:16.854775807
1 2018-01-31 2018-07-31 2019-01-31 2262-04-11 23:47:16.854775807
2 2018-01-31 2018-07-31 2019-01-31 2262-04-11 23:47:16.854775807
4 2020-01-08 2020-07-08 2021-01-08 2262-04-11 23:47:16.854775807
5 2020-01-08 2020-07-08 2021-01-08 2262-04-11 23:47:16.854775807
6 2020-01-08 2020-07-08 2021-01-08 2262-04-11 23:47:16.854775807
7 2020-01-08 2020-07-08 2021-01-08 2262-04-11 23:47:16.854775807
>>> between = dates.le(df['Date'], axis='index') & next_date.gt(df['Date'], axis='index')
>>> between
min + 0m  min + 6m  min + 12m  min + 18m
0      True     False      False      False
1     False      True      False      False
2     False     False       True      False
4      True     False      False      False
5      True     False      False      False
6      True     False      False      False
7      True     False      False      False
>>> between.groupby(df['ID']).sum()
min + 0m  min + 6m  min + 12m  min + 18m
ID                                           
1           1         1          1          0
13          4         0          0          0

相关内容

  • 没有找到相关文章

最新更新