在熊猫数据框中按日期范围分组

时间:2019-02-19 23:31:30

标签: python pandas

我有一个大熊猫的时间序列数据,我想按每年的某个时间窗口分组并计算其最小值和最大值。

例如:

times = pd.date_range(start = '1/1/2011', end = '1/1/2016', freq = 'D')
df = pd.DataFrame(np.random.rand(len(times)), index=times, columns=["value"])

如何对每年的时间窗口e.g. 'Jan-10':'Mar-21'进行分组,并计算其在列value中的最小值和最大值?

3 个答案:

答案 0 :(得分:2)

我不确定是否有一种直接的方法可以在没有首先创建所需日子的标记的情况下进行操作。以下函数用于创建所需的标志:

# Function for flagging the days required    
def flag(x):
    if x.month == 1 and x.day>=10: return True
    elif x.month in [2,3,4]: return True
    elif x.month == 5 and x.day<=21: return True
    else: return False

由于您需要每年,因此最好将年份作为一列。 然后,可以使用以下代码获取给定时间段内每年的最小值和最大值:

times = pd.date_range(start = '1/1/2011', end = '1/1/2016', freq = 'D')
df = pd.DataFrame(np.random.rand(len(times)), index=times, columns=["value"])
df['Year'] = df.index.year
pd.pivot_table(df[list(pd.Series(df.index).apply(flag))], values=['value'], index = ['Year'], aggfunc=[min,max])

输出将如下所示: Sample Output

希望能回答您的问题...:)

答案 1 :(得分:0)

您可以使用重采样方法。

df.resample('5d').agg(['min','max'])

答案 2 :(得分:0)

您可以定义垃圾箱边缘,然后用.loc[::2, :]丢弃不需要的垃圾箱(其他)。在这里,我将定义两个函数,以检查是否在组中获取了我们想要的日期范围(请注意,因为左侧边缘是开放的,需要减去1天):

import pandas as pd

edges = pd.to_datetime([x for year in df.index.year.unique() 
                        for x in [f'{year}-02-09', f'{year}-03-21']])

def min_idx(x):
    return x.index.min()
def max_idx(x):
    return x.index.max()

df.groupby(pd.cut(df.index, bins=edges)).agg([min_idx, max_idx, min, max]).loc[::2, :]

输出:

                              value                               
                            min_idx    max_idx       min       max
(2011-02-09, 2011-03-21] 2011-02-10 2011-03-21  0.009343  0.990564
(2012-02-09, 2012-03-21] 2012-02-10 2012-03-21  0.026369  0.978470
(2013-02-09, 2013-03-21] 2013-02-10 2013-03-21  0.039491  0.946481
(2014-02-09, 2014-03-21] 2014-02-10 2014-03-21  0.029161  0.967490
(2015-02-09, 2015-03-21] 2015-02-10 2015-03-21  0.006877  0.969296
(2016-02-09, 2016-03-21]        NaT        NaT       NaN       NaN