我有一个日期不完整的DataFrame,我只需要每月可用的最后一天的日期/行。
我尝试使用TimeGrouper并获取每个组的.last()
。
import pandas as pd
idx = [pd.datetime(2016,2,1),pd.datetime(2017,1,20),pd.datetime(2017,2,1),pd.datetime(2017,2,27)]
df = pd.DataFrame([1,2,3,4],index=idx)
df
0
2016-02-01 1
2017-01-20 2
2017-02-01 3
2017-02-27 4
期待:
df_eom
0
2016-02-01 1
2017-01-20 2
2017-02-27 4
然而我得到了这个:
df_eom = df.groupby(pd.TimeGrouper(freq='1M')).last()
df_eom
0
2016-02-29 1.0
2016-03-31 NaN
2016-04-30 NaN
2016-05-31 NaN
2016-06-30 NaN
2016-07-31 NaN
2016-08-31 NaN
2016-09-30 NaN
2016-10-31 NaN
2016-11-30 NaN
2016-12-31 NaN
2017-01-31 2.0
2017-02-28 4.0
不仅创建了不在df中的日期,还改变了df的第一行和最后一行的索引。我使用TimeGrouper错了吗?
答案 0 :(得分:1)
这是单程
In [795]: df.iloc[df.reset_index().groupby(df.index.to_period('M'))['index'].idxmax()]
Out[795]:
0
2016-02-01 1
2017-01-20 2
2017-02-27 4
或者
In [802]: df.loc[df.groupby(df.index.to_period('M')).apply(lambda x: x.index.max())]
Out[802]:
0
2016-02-01 1
2017-01-20 2
2017-02-27 4
答案 1 :(得分:0)
我相信这个解决方案更适合更多用例。以前的实例仅在日期正好是月末时才有效。例如,如果您处理财务数据,则该月的最后一天可能是也可能不是日历月末。此解决方案说明了这一点:
df[df['as_of_date'].dt.month.shift(-1)!=df['as_of_date'].dt.month].reset_index(drop=True)
答案 2 :(得分:-1)
您可以按年份和月份进行分组,并遍历您的群组以查找上次日期。像这样:
groups = df.groupby([df.index.year, df.index.month])
df_eom = pd.DataFrame()
for idx, group in groups:
df_eom = df_eom.append(group.iloc[-1])
df_eom
0
2016-02-01 1
2017-01-20 2
2017-02-27 4
由于循环,我不是很喜欢这个,但考虑到你真的不能有多少年,而且每年最多有12个月的小组,所以不应该这样。太可怕了。