我有一个数据帧df
,其中df.index
是DatetimeIndex
。我正在尝试筛选倒数第二个可用天。
如果我没有弄错,tseries.offsets.DateOffset
可能会返回我的列表中没有包含的日期,这不是我想要的。
我试过:
df.groupby([df.index.year, df.index.month]).tail(2)
df.groupby([df.index.year, df.index.month]).loc(-2)
df
:
value
2020-08-29 0
2020-08-31 0
2020-09-01 0
2020-09-25 0
2020-09-26 0
2020-09-30 0
获取:
value
2020-08-29 0
2020-09-26 0
听起来您正试图获取所列日期的倒数第二天。要实现这一点,如果日期列中有唯一的日期,则可以使用以下代码。如果你有一些重复的日期,那么你可能不得不尝试另一种方法。
使用这种方法,您可以找到每月的max
日期(dt.month
(,并与之前的一行进行比较,以筛选所列日期的倒数第二行:
import pandas as pd
df = pd.DataFrame({'Date': {0: '2020-08-29',
1: '2020-08-31',
2: '2020-09-01',
3: '2020-09-25',
4: '2020-09-26',
5: '2020-09-30'},
'value': {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0}})
df['Date'] = pd.to_datetime(df['Date']).sort_values()
m = (df.groupby(df['Date'].dt.month)['Date'].transform('max') == df['Date'].shift(-1))
df = df[m]
df
Out[27]:
Date value
0 2020-08-29 0
4 2020-09-26 0
如果有用的话,我将m
(m
代表"掩码",因为我们正在进行布尔掩码/索引(方程的每一边分解为m1
和m2
,向您展示它是如何工作的。然后,我为m1、m2和m创建列,这样您就可以看到所有逻辑是如何工作的:
import pandas as pd
df = pd.DataFrame({'Date': {0: '2020-08-29',
1: '2020-08-31',
2: '2020-09-01',
3: '2020-09-25',
4: '2020-09-26',
5: '2020-09-30'},
'value': {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0}})
df['Date'] = pd.to_datetime(df['Date']).sort_values()
m1 = df.groupby(df['Date'].dt.month)['Date'].transform('max')
m2 = df['Date'].shift(-1)
m = (m1 == m2)
df['Max Date Per Month'] = m1
df['Shifted Date'] = m2
df['Keep/Drop'] = m
df
Out[33]:
Date value Max Date Per Month Shifted Date Keep/Drop
0 2020-08-29 0 2020-08-31 2020-08-31 True
1 2020-08-31 0 2020-08-31 2020-09-01 False
2 2020-09-01 0 2020-09-30 2020-09-25 False
3 2020-09-25 0 2020-09-30 2020-09-26 False
4 2020-09-26 0 2020-09-30 2020-09-30 True
5 2020-09-30 0 2020-09-30 NaT False
我们可以进行duplicated
df = df[df.index.strftime('%Y-%m').duplicated()]
Out[22]:
value
2020-08-31 0
2020-09-25 0
2020-09-26 0
2020-09-30 0
取每月最后两天,然后取每月两天中的第一天
df = df.groupby([df.index.year, df.index.month]).tail(2)
df.groupby([df.index.year, df.index.month]).head(1)