Pandas DataFrame:选择每月数据的最后一天

时间:2018-02-22 04:57:12

标签: pandas

这是我的DataFrame

>> df

              open        high         low        close      volume
date                    
2017-01-02  778000.0    787000.0    775000.0    777000.0    30777.0
2017-01-03  777000.0    777000.0    767000.0    767000.0    51766.0
2017-01-04  775000.0    810000.0    771000.0    810000.0    120359.0
2017-02-02  776000.0    780000.0    770000.0    772000.0    121050.0
2017-02-03  770000.0    776000.0    767000.0    774000.0    142414.0
2017-02-06  781000.0    781000.0    772000.0    779000.0    127029.0
2017-03-07  800000.0    806000.0    794000.0    799000.0    48316.0
2017-03-08  798000.0    807000.0    791000.0    800000.0    56378.0

我想要做的是选择每月最后一天的数据:

              open        high        low        close        volume
date                    
2017-01-04  775000.0    810000.0    771000.0    810000.0    120359.0
2017-02-06  781000.0    781000.0    772000.0    779000.0    127029.0
2017-03-08  798000.0    807000.0    791000.0    800000.0    56378.0

我尝试了什么:

a.resample('M').apply(lambda x: x[-1])  # Doesn't work => `date` is not correct

              open         high       low        close       volume
date                    
2017-01-31  775000.0    810000.0    771000.0    810000.0    120359.0
2017-02-28  781000.0    781000.0    772000.0    779000.0    127029.0
2017-03-31  798000.0    807000.0    791000.0    800000.0    56378.0 

需要你的帮助

由于

3 个答案:

答案 0 :(得分:2)

以下是几种方式

<强> 1)

In [779]: df.iloc[df.reset_index().groupby(df.index.strftime('%Y-%m'))['date'].idxmax()]
Out[779]:
                open      high       low     close    volume
date
2017-01-04  775000.0  810000.0  771000.0  810000.0  120359.0
2017-02-06  781000.0  781000.0  772000.0  779000.0  127029.0
2017-03-08  798000.0  807000.0  791000.0  800000.0   56378.0

2)

In [813]: df.loc[df.reset_index().groupby(df.index.to_period('M'))['date'].max()]
Out[813]:
                open      high       low     close    volume
date
2017-01-04  775000.0  810000.0  771000.0  810000.0  120359.0
2017-02-06  781000.0  781000.0  772000.0  779000.0  127029.0
2017-03-08  798000.0  807000.0  791000.0  800000.0   56378.0

3)

In [810]: df.loc[df.groupby(df.index.to_period('M')).apply(lambda x: x.index.max())]
Out[810]:
                open      high       low     close    volume
date
2017-01-04  775000.0  810000.0  771000.0  810000.0  120359.0
2017-02-06  781000.0  781000.0  772000.0  779000.0  127029.0
2017-03-08  798000.0  807000.0  791000.0  800000.0   56378.0

4)

In [105]: df.reset_index().groupby(df.index.to_period('M')).last().set_index('date')

详细

In [783]: df.index.strftime('%Y-%m')
Out[783]:
array([u'2017-01', u'2017-01', u'2017-01', u'2017-02', u'2017-02',
       u'2017-02', u'2017-03', u'2017-03'],
      dtype='<U7')

In [784]: df.reset_index().groupby(df.index.strftime('%Y-%m'))['date'].idxmax()
Out[784]:
2017-01    2
2017-02    5
2017-03    7
Name: date, dtype: int64

答案 1 :(得分:1)

您可以按月分组,然后选择当月最长日期的记录:

(
    df.groupby(df.date.dt.to_period('M'))
    .apply(lambda x: x.loc[x.date.idxmax()])
    .set_index('date')
)
Out[758]: 
                open      high       low     close    volume
date                                                        
2017-01-04  775000.0  810000.0  771000.0  810000.0  120359.0
2017-02-06  781000.0  781000.0  772000.0  779000.0  127029.0
2017-03-08  798000.0  807000.0  791000.0  800000.0   56378.0

另一种方法是先按日期排序DF,然后从每个月开始最后一行。

(
    df.sort_values(by='date')
    .groupby(df.date.dt.to_period('M'))
    .last()
    .set_index('date')
)

答案 2 :(得分:1)

没有groupby(适用于已排序的ddf,如果不首先应用df=df.sort_index()

df[~pd.Series(df.index.strftime('%Y%m')).duplicated(keep='last').values]
Out[120]: 
                open      high       low     close    volume
date                                                        
2017-01-04  775000.0  810000.0  771000.0  810000.0  120359.0
2017-02-06  781000.0  781000.0  772000.0  779000.0  127029.0
2017-03-08  798000.0  807000.0  791000.0  800000.0   56378.0