2019年5月2日 星期四

[Python] 時間處理

時間處理是實際工作中常運到的問題, 這裡整理資料前處理可能遇到的時間處理的問題

計時器
from datetime import datetime
def timer(start_time=None):
    if not start_time:
        start_time = datetime.now()
        return start_time
    elif start_time:
        thour, temp_sec = divmod((datetime.now() - start_time).total_seconds(), 3600)
        tmin, tsec = divmod(temp_sec, 60)
        print('\n Time taken: %i hours %i minutes and %s seconds.' % (thour, tmin, round(tsec, 2)))

#use
start_time = timer()

#wait ...

timer(start_time )
pandas 時間轉換
def augFeatures(train):
  train["Date"] = pd.to_datetime(train["Date"])
  train["year"] = train["Date"].dt.year
  train["month"] = train["Date"].dt.month
  train["date"] = train["Date"].dt.day
  train["day"] = train["Date"].dt.dayofweek
  return train
python datetime處理時間範例
   def add_months(self, dt, months):
        """
        加減月份
        """

        if dt.year <= 1900:
            dt.replace(year=1900)
        month = dt.month - 1 + months
        year = dt.year + month / 12
        month = month % 12 + 1
        day = min(dt.day, calendar.monthrange(year, month)[1])
        return dt.replace(year=year, month=month, day=day)

    def get_month_range_days(self, _year, _month):
        """
        取得月份天數
        """

        return calendar.monthrange(_year, _month)

    def get_this_week_range(self):
        """
        取得本周頭尾日期
        """

        # if start_date is None:
        start_date = date.today() - timedelta(days=date.today().weekday())
        end_date = date.today() + timedelta(days=6 - date.today().weekday())
        return start_date, end_date

    def get_this_month_range(self, _start_date):
        """
        取得本月頭尾日期
        """

        if _start_date is None:
            start_date = date.today().replace(day=1)
        else:
            start_date = _start_date.replace(day=1)
        _, days_in_month = calendar.monthrange(start_date.year, start_date.month)
        end_date = start_date + timedelta(days=days_in_month) - timedelta(days=(1))
        return start_date, end_date

    def get_this_year_range(self, _start_date):
        """
        取得本年頭尾日期
        """

        if _start_date is None:
            start_date = date.today().replace(month=1, day=1)
            end_date = date.today().replace(month=12, day=31)
        else:
            start_date = _start_date.replace(year=_start_date.year, month=1, day=1)
            end_date = _start_date.replace(year=_start_date.year, month=12, day=31)

        return start_date, end_date
用正規表示法處理時間範例
    def norm_setyear(self):
        """
        年-規範化方法--該方法識別時間表達式單元的年欄位
        :return:
        """
        # 一位數表示的年份
        rule = u"(?<![0-9])[0-9]{1}(?=年)"
        pattern = re.compile(rule)
        match = pattern.search(self.exp_time)
        if match is not None:
            self.normalizer.isTimeSpan = True
            year = int(match.group())
            self.tp.tunit[0] = year

        # 兩位數表示的年份
        rule = u"[0-9]{2}(?=年)"
        pattern = re.compile(rule)
        match = pattern.search(self.exp_time)
        if match is not None:
            year = int(match.group())
            self.tp.tunit[0] = year

        # 三位數表示的年份
        rule = u"(?<![0-9])[0-9]{3}(?=年)"
        pattern = re.compile(rule)
        match = pattern.search(self.exp_time)
        if match is not None:
            self.normalizer.isTimeSpan = True
            year = int(match.group())
            self.tp.tunit[0] = year

        # 四位數表示的年份
        rule = u"[0-9]{4}(?=年)"
        pattern = re.compile(rule)
        match = pattern.search(self.exp_time)
        if match is not None:
            year = int(match.group())
            self.tp.tunit[0] = year

    def norm_setmonth(self):
        """
        月-規範化方法--該方法識別時間表達式單元的月欄位
        :return:
        """
        rule = u"((10)|(11)|(12)|([1-9]))(?=月)"
        pattern = re.compile(rule)
        match = pattern.search(self.exp_time)
        if match is not None:
            self.tp.tunit[1] = int(match.group())


    def norm_setmonth_fuzzyday(self):
        """
        月-日 兼容模糊寫法:該方法識別時間表達式單元的月、日欄位
        :return:
        """

        rule = u"((10)|(11)|(12)|([1-9]))(月|\\.|\\-|\\/|\\\)([0-3][0-9]|[1-9])"
        pattern = re.compile(rule)
        match = pattern.search(self.exp_time)
        if match is not None:

            matchStr = match.group()
            p = re.compile(u"(月|\\.|\\-)")
            m = p.search(matchStr)
            if match is not None:
                  splitIndex = m.start()
                month = matchStr[0: splitIndex]
                day = matchStr[splitIndex + 1:]
                self.tp.tunit[1] = int(month)
                self.tp.tunit[2] = int(day)
 
    def norm_setday(self):
        """
        日-規範化方法:該方法識別時間表達式單元的日欄位
        :return:
        """
        rule = u"((?<!\\d))([0-3][0-9]|[1-9])(?=(日|號))"
        pattern = re.compile(rule)
        match = pattern.search(self.exp_time)
        if match is not None:
            self.tp.tunit[2] = int(match.group())
計算時間decorator
def timeit_wrapper(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()  # Alternatively, you can use time.process_time()
        func_return_val = func(*args, **kwargs)
        end = time.perf_counter()
        print('{0:<10}.{1:<8} : {2:<8}'.format(func.__module__, func.__name__, end - start))
        return func_return_val
    return wrapper

沒有留言:

張貼留言