从pandas数据框中删除非工作日行

37

我有一个带有小麦时间序列数据的数据框 df

df = wt["WHEAT_USD"]

2016-05-02 02:00:00+02:00    4.780
2016-05-02 02:01:00+02:00    4.777
2016-05-02 02:02:00+02:00    4.780
2016-05-02 02:03:00+02:00    4.780
2016-05-02 02:04:00+02:00    4.780
Name: closeAsk, dtype: float64

当我绘制数据时,由于周末的原因,它会出现这些令人讨厌的水平线。有没有一种简单的方法从数据框本身中去除非工作日?

类似于

df = df.BDays()
6个回答

58

一种简单的解决方案是切片出周一到周五以外的日期:

In [11]: s[s.index.dayofweek < 5]
Out[11]:
2016-05-02 00:00:00    4.780
2016-05-02 00:01:00    4.777
2016-05-02 00:02:00    4.780
2016-05-02 00:03:00    4.780
2016-05-02 00:04:00    4.780
Name: closeAsk, dtype: float64

注意:此处未考虑银行假期等因素。


感谢您的帮助! - vandelay

16

Pandas的BDay仅仅使用.dayofweek<5来实现,就像所选择的答案一样,但是可以扩展以包括银行假期等。

import pandas as pd
from pandas.tseries.offsets import BDay

isBusinessDay = BDay().onOffset
csv_path = 'C:\\Python27\\Lib\\site-packages\\bokeh\\sampledata\\daylight_warsaw_2013.csv'
dates_df = pd.read_csv(csv_path)
match_series = pd.to_datetime(dates_df['Date']).map(isBusinessDay)
dates_df[match_series]

3

我正在构建一个股票/外汇交易的回测程序,但遇到了日期是nan(非数字)的问题,可能是节假日或其他非交易日导致的。 你可以下载金融日历来确定没有交易的日期,然后需要考虑时区和周末等因素。

但是最好的解决方案不是使用日期/时间作为蜡烛图或价格的索引。 所以不要将您的价格数据与日期/时间相连,而是与蜡烛图或价格的计数器相连...您可以使用第二个索引来实现这一点... 因此,在计算移动平均线或其他技术线时,不要使用日期/时间.. 如果您看一下MetaTrader 4/5,它也不使用日期/时间,而是使用数据的蜡烛图编号作为索引!!

我认为在处理股票或外汇数据时,您需要放弃日期时间对于价格的影响,当然您可以将其放入数据框中的一列,但不要将其用作索引 这样可以避免许多问题。


0
借鉴@Andy Hayden的解决方案,您还可以使用dataframe中的query进行更好的方法链接,以"现代pandas"的方式。

如果日期是一列(例如命名为my_date

df.query("my_date.dt.dayofweek < 5")

如果日期是索引并且有一个名称(例如my_index_namedate
df.query("my_index_name.dt.dayofweek < 5")

如果日期是索引且没有名称

df.rename_axis("date").query("date.dt.dayofweek < 5")

(index.dt.dayofweekindex.dayofweek对我不起作用)。


0

简单来说,可以通过星期几进行过滤。例如,如果您不想要周六和周日,可以使用以下代码:

df=df[(df['date'].dt.day_name()!='Saturday') & (df['date'].dt.day_name()!='Sunday')]

不包括特别的节假日等


0

使用工作日函数,您可以轻松计算假期。

    import workdays as wd

    def drop_non_busdays(df, holidays=None):
        if holidays is None:
            holidays = []
        start_date = df.index.to_list()[0].date()
        end_date = df.index.to_list()[-1].date()


        start_wd = wd.workday(wd.workday(start_date, -1, holidays), 1, holidays)
        end_wd = wd.workday(wd.workday(end_date, 1, holidays), -1, holidays)

        b_days = [start_wd]
        while b_days[-1] < end_wd:
            b_days.append(wd.workday(b_days[-1], 1, holidays))

        valid = [i in b_days for i in df.index]
        return df[valid]

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