在最近的n个日期内过滤Pandas DataFrame

7

我有一个 Pandas 数据框,看起来像这样:

df

我希望使用一个本地定义的整数参数 'days' 过滤数据框。例如当 days=10 时,我过滤出的数据框仅包含最近可用的 10 个日期的数据。

到目前为止,我尝试了以下方法:

days=10    
cutoff_date = df["SeriesDate"][-1:] - datetime.timedelta(days=days)

然而,当尝试输出已过滤的DF时,使用以下命令:

df[df['SeriesDate'] > cutoff_date] 

我收到了以下错误信息:

我遇到了以下错误:

ValueError: Can only compare identically-labeled Series objects

我仍在学习Python,因此会感激任何可以帮助我的人。


我不确定我理解你的问题:你需要首先为每行创建一个截止日期,然后相应地进行筛选吗? - lorenzori
我想根据传入的天数输出经过DF筛选的结果。如果days = 10,则输出DF中最后10个值。因此,如果最后可用日期是2017年2月27日,则我的输出序列应仅包含2017年2月17日之后的值。 - sg91
为什么要用 [-1:] 删除最后一个项目 df["SeriesDate"][-1:]?因为这样会导致序列的索引不同(最后一个项目被删除),从而导致错误。 - jezrael
或者如果只需要列的最后一个值,则可能需要 cutoff_date = df["SeriesDate"].iloc[-1] - datetime.timedelta(days=days) - jezrael
@jezrael 谢谢,除此之外我还能用什么方法得到我想要过滤数据的日期呢? - sg91
显示剩余2条评论
1个回答

5

我认为您需要使用iloc,选择SeriesDate列的最后一个值:

start = pd.to_datetime('2015-02-24')
rng = pd.date_range(start, periods=15, freq='20H')
df = pd.DataFrame({'SeriesDate': rng, 'Value_1': np.random.random(15)})  
print (df)
            SeriesDate   Value_1
0  2015-02-24 00:00:00  0.849160
1  2015-02-24 20:00:00  0.332487
2  2015-02-25 16:00:00  0.687638
3  2015-02-26 12:00:00  0.310326
4  2015-02-27 08:00:00  0.660795
5  2015-02-28 04:00:00  0.354475
6  2015-03-01 00:00:00  0.061312
7  2015-03-01 20:00:00  0.443908
8  2015-03-02 16:00:00  0.708326
9  2015-03-03 12:00:00  0.257419
10 2015-03-04 08:00:00  0.618363
11 2015-03-05 04:00:00  0.121625
12 2015-03-06 00:00:00  0.637324
13 2015-03-06 20:00:00  0.058292
14 2015-03-07 16:00:00  0.047624

days=10    
cutoff_date = df["SeriesDate"].iloc[-1] - pd.Timedelta(days=days)
print (cutoff_date)
2015-02-25 16:00:00

df1 = df[df['SeriesDate'] > cutoff_date] 
print (df1)
            SeriesDate   Value_1
3  2015-02-26 12:00:00  0.310326
4  2015-02-27 08:00:00  0.660795
5  2015-02-28 04:00:00  0.354475
6  2015-03-01 00:00:00  0.061312
7  2015-03-01 20:00:00  0.443908
8  2015-03-02 16:00:00  0.708326
9  2015-03-03 12:00:00  0.257419
10 2015-03-04 08:00:00  0.618363
11 2015-03-05 04:00:00  0.121625
12 2015-03-06 00:00:00  0.637324
13 2015-03-06 20:00:00  0.058292
14 2015-03-07 16:00:00  0.047624

另一个选择是使用max,感谢Pocin提供的建议:

cutoff_date = df["SeriesDate"].max() - pd.Timedelta(days=days)
print (cutoff_date)
2015-02-25 16:00:00

如果你只想按照日期过滤:

days=10    
cutoff_date = df["SeriesDate"].dt.date.iloc[-1] - pd.Timedelta(days=days)
print (cutoff_date)
2015-02-25

编辑:

你可以用dayofweek筛选出周末的日期,然后使用isin函数。

start = pd.to_datetime('2015-02-24')
rng = pd.date_range(start, periods=15)
df = pd.DataFrame({'SeriesDate': rng, 'Value_1': np.random.random(15)})  
print (df)
   SeriesDate   Value_1
0  2015-02-24  0.498387
1  2015-02-25  0.435767
2  2015-02-26  0.299233
3  2015-02-27  0.489286
4  2015-02-28  0.892167
5  2015-03-01  0.507436
6  2015-03-02  0.360427
7  2015-03-03  0.903886
8  2015-03-04  0.718148
9  2015-03-05  0.645489
10 2015-03-06  0.251285
11 2015-03-07  0.139275
12 2015-03-08  0.756845
13 2015-03-09  0.565863
14 2015-03-10  0.148077

days=10    
last_day = df["SeriesDate"].dt.date.iloc[-1]
cutoff_date = last_day - pd.Timedelta(days=days)
rng = pd.date_range(cutoff_date, last_day)

rng = rng[(rng.dayofweek != 0) & (rng.dayofweek != 6)]
print (rng)
DatetimeIndex(['2015-02-28', '2015-03-03', '2015-03-04', '2015-03-05',
               '2015-03-06', '2015-03-07', '2015-03-10'],
              dtype='datetime64[ns]', freq=None)

df1 = df[df['SeriesDate'].isin(rng)]
print (df1)
   SeriesDate   Value_1
4  2015-02-28  0.892167
7  2015-03-03  0.903886
8  2015-03-04  0.718148
9  2015-03-05  0.645489
10 2015-03-06  0.251285
11 2015-03-07  0.139275
14 2015-03-10  0.148077

1
不要依赖于datetime索引已排序并使用iloc[-1],而是使用df['SeriesDate'].max()可能是一个可行的替代方案。 - redacted
谢谢两位,是否有可能到达截止日期,以便忽略周末日期?也就是说,如果天数=10,则截止日期是忽略周末的前十天日期。也就是只包括工作日。 - sg91

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接