Python 熊猫-获取两个日期之间的所有行,但仅限于特定的工作日和时间段

Python 熊猫-获取两个日期之间的所有行,但仅限于特定的工作日和时间段,python,pandas,datetimeindex,Python,Pandas,Datetimeindex,假设我有一个如下所示的数据帧: usage_price 2017-04-01 00:00:00 1 2017-04-01 00:30:00 1 2017-04-01 01:00:00 1 2017-04-01 01:30:00 1 2017-04-01 02:00:00 1 ... ... 201

假设我有一个如下所示的数据帧:

                     usage_price
2017-04-01 00:00:00            1
2017-04-01 00:30:00            1
2017-04-01 01:00:00            1
2017-04-01 01:30:00            1
2017-04-01 02:00:00            1
...                          ...
2018-12-31 22:00:00            1
2018-12-31 22:30:00            1
2018-12-31 23:00:00            1
2018-12-31 23:30:00            1
我要做的是更新特定字段的
用法\u价格
。在我的情况下,我希望基于此对象进行更新:

{'day': '1', 'timerange': ['01 01 00:00', '31 12 08:00']}
即:

  • 更新所有星期一('day':'1')
  • 在00:00和08:00之间
  • 在01-01(1月1日)和31-12(12月31日)之间的任何星期一(忽略年份)
我知道如何分别做这些事情:

  • df_timeseries[df_timeseries.index.weekday==0,'使用价格]
  • df\u timeseries.loc[df\u timeseries.between\u time('00:00','08:00',include\u end=False).索引,'usage\u price']
但我有点被困在如何在日期之间取得行(忽略年份),以及如何将所有内容结合在一起-因此,非常感谢您的帮助

编辑:这是我所能达到的程度,但我似乎无法让它工作(我遇到语法错误),我不认为我将以正确的方式额外构建掩码:

def _create_mask_from_tpr(self, df: pd.DataFrame, tpr: Dict[str, Union[str, List[str]]]) -> Tuple:
    print(tpr)
    weekday = int(tpr['day']) - 1 # Offset.
    start_day, start_month, start_time = tpr['timerange'][0].split(" ")
    end_day, end_month, end_time = tpr['timerange'][1].split(" ")
    start_year, end_year = df.index.min().year, df.index.max().year
    selection_weekday = (df.index.weekday == weekday)
    selection_time = (df.between_time(start_time, end_time))

    selection_date = None
    for year in range(start_year, end_year + 1):
        start_date = pd.to_datetime("{}-{}-{}".format(year, start_month, start_day))
        end_date = pd.to_datetime("{}-{}-{}".format(year, end_month, end_day))
        selection_date = selection_date | (df.index.date() >= start_date & df.index.date() <= end_date)
    mask = (selection_weekday & selection_time & selection_date)
    print(mask)
def\u从tpr创建掩码(self,df:pd.DataFrame,tpr:Dict[str,Union[str,List[str]])->元组:
打印(tpr)
工作日=整数(tpr['day'])-1#偏移量。
开始日,开始月,开始时间=tpr['timerange'][0]。拆分(“”)
结束日,结束月,结束时间=tpr['timerange'][1]。拆分(“”)
开始年份,结束年份=df.index.min().year,df.index.max().year
选择_weekday=(df.index.weekday==weekday)
选择时间=(df.between时间(开始时间、结束时间))
选择日期=无
对于范围内的年份(开始年份、结束年份+1):
start_date=pd.to_datetime(“{}-{}-{}.”格式(年、月、日)
end_date=pd.to_datetime(“{}-{}-{}”.format(年、月、日))

selection_date=selection_date |(df.index.date()>=start_date&df.index.date()未经测试,但可以使用以下方法:

selection = ((df_timeseries.index.weekday == 0) & 
             (df_timeseries.between_time('00:00', '08:00', include_end=False)))
result = df_timeseries[selection, 'usage_price']
通常,您可以将比较与
|
&
运算符结合使用(但使用括号)。 因为开始日期和结束日期都包括全年,所以我没有对此进行筛选

如果您想选择日期,而不指定年份,则在执行时会遇到问题,例如:您可能必须执行以下操作:

selection = ((df_timeseries.index.day >= 5) &
             (df_timeseries.index.day <= 20) &
             (df_timeseries.index.day >= 2) &
             (df_timeseries.index.day <= 3))

未经测试,但按照以下思路可以工作:

selection = ((df_timeseries.index.weekday == 0) & 
             (df_timeseries.between_time('00:00', '08:00', include_end=False)))
result = df_timeseries[selection, 'usage_price']
通常,您可以将比较与
|
&
运算符结合使用(但使用括号)。 因为开始日期和结束日期都包括全年,所以我没有对此进行筛选

如果您想选择日期,而不指定年份,则在执行时会遇到问题,例如:您可能必须执行以下操作:

selection = ((df_timeseries.index.day >= 5) &
             (df_timeseries.index.day <= 20) &
             (df_timeseries.index.day >= 2) &
             (df_timeseries.index.day <= 3))
最终解决方案:

def _create_mask_from_tpr(self, df: pd.DataFrame, tpr: Dict[str, Union[str, List[str]]]) -> List[bool]:
    weekday = int(tpr['day']) - 1 # Offset.
    start_day, start_month, start_time = tpr['timerange'][0].split(" ")
    end_day, end_month, end_time = tpr['timerange'][1].split(" ")
    start_year, end_year = df.index.min().year, df.index.max().year
    selection_weekday = (df.index.weekday == weekday)

    start_time = datetime.datetime.strptime(start_time, '%H:%M').time()
    end_time = datetime.datetime.strptime(end_time, '%H:%M').time()
    selection_time = ((df.index.time >= start_time) & (df.index.time <= end_time))

    selection_date = None
    for year in range(start_year, end_year + 1):
        start_date = pd.Timestamp("{}-{}-{}".format(year, start_month, start_day))
        end_date = pd.Timestamp("{}-{}-{}".format(year, end_month, end_day))
        if selection_date:
            selection_date = selection_date | ((df.index >= start_date) & (df.index <= end_date))
        else:
            selection_date = ((df.index >= start_date) & (df.index <= end_date))
    return (selection_weekday & selection_time & selection_date)
def\u从tpr创建掩码(self,df:pd.DataFrame,tpr:Dict[str,Union[str,List[str]])->List[bool]:
工作日=整数(tpr['day'])-1#偏移量。
开始日,开始月,开始时间=tpr['timerange'][0]。拆分(“”)
结束日,结束月,结束时间=tpr['timerange'][1]。拆分(“”)
开始年份,结束年份=df.index.min().year,df.index.max().year
选择_weekday=(df.index.weekday==weekday)
开始时间=datetime.datetime.strtime(开始时间,%H:%M').time()
end_time=datetime.datetime.strtime(end_time,“%H:%M”).time()
选择时间=((df.index.time>=开始时间)&(df.index.time=开始日期)&(df.index=开始日期)&(df.index最终解决方案:

def _create_mask_from_tpr(self, df: pd.DataFrame, tpr: Dict[str, Union[str, List[str]]]) -> List[bool]:
    weekday = int(tpr['day']) - 1 # Offset.
    start_day, start_month, start_time = tpr['timerange'][0].split(" ")
    end_day, end_month, end_time = tpr['timerange'][1].split(" ")
    start_year, end_year = df.index.min().year, df.index.max().year
    selection_weekday = (df.index.weekday == weekday)

    start_time = datetime.datetime.strptime(start_time, '%H:%M').time()
    end_time = datetime.datetime.strptime(end_time, '%H:%M').time()
    selection_time = ((df.index.time >= start_time) & (df.index.time <= end_time))

    selection_date = None
    for year in range(start_year, end_year + 1):
        start_date = pd.Timestamp("{}-{}-{}".format(year, start_month, start_day))
        end_date = pd.Timestamp("{}-{}-{}".format(year, end_month, end_day))
        if selection_date:
            selection_date = selection_date | ((df.index >= start_date) & (df.index <= end_date))
        else:
            selection_date = ((df.index >= start_date) & (df.index <= end_date))
    return (selection_weekday & selection_time & selection_date)
def\u从tpr创建掩码(self,df:pd.DataFrame,tpr:Dict[str,Union[str,List[str]])->List[bool]:
工作日=整数(tpr['day'])-1#偏移量。
开始日,开始月,开始时间=tpr['timerange'][0]。拆分(“”)
结束日,结束月,结束时间=tpr['timerange'][1]。拆分(“”)
开始年份,结束年份=df.index.min().year,df.index.max().year
选择_weekday=(df.index.weekday==weekday)
开始时间=datetime.datetime.strtime(开始时间,%H:%M').time()
end_time=datetime.datetime.strtime(end_time,“%H:%M”).time()

选择时间=((df.index.time>=开始时间)&(df.index.time=开始日期)&(df.index=开始日期)&(df.index=开始日期)&(df.index我已经尝试过了,但我不确定复杂的链接是否有效。我已经在我的问题中添加了我的尝试,但是我得到了
选择日期=选择日期|(df.index.date()>=开始日期和df.index.date()@Darkstarone通读可能会有所帮助,尤其是“布尔运算符”部分。它主要关注NumPy,大部分时间与熊猫几乎相同。我尝试过这样做,但我不确定复杂的链接是否有效。我已将我的尝试添加到我的问题中,但我得到了
selection_date=selection_date|(df.index.date()>=start_date&df.index.date()@Darkstarone通读可能会有所帮助,尤其是“布尔运算符”部分。它主要关注NumPy,大部分时间与熊猫差不多。