【问题标题】:Python: How to find the nth weekday of the year?Python:如何找到一年中的第 n 个工作日?
【发布时间】:2020-04-08 17:05:02
【问题描述】:

我在“每月的第 n 个工作日”看到了很多类似的帖子,但我的问题与“一年中的第 n 个工作日”有关。

背景: 我有一张包含每日销售数据的表格。有 3 列:日期、星期几(周一、周二、周三等)和销售额。我想将第 1 年的第 n 个工作日与第 2 年匹配,并以这种方式比较销售额。

  • 示例 1:01/06/2020 与 01/04/2021 匹配,都是当年的第一个星期一。
  • 示例 2:11/02/2019 与 10/31/2020 匹配,都是当年的第 44 个星期六。

如您所见,我不能简单地做“本月的第 n 个工作日”,因为有时匹配的第 n 个工作日会落在不同的月份(如 2019 年 11 月 2 日和 2020 年 10 月 31 日所示)。

我正在处理 pandas 中的表格。我想知道是否有一种快速的方法可以让我创建一个列来帮助我为我计算“一年中的第 n 个工作日”,以便我以后可以根据该值进行匹配?

感谢您的帮助。

【问题讨论】:

  • 进一步迭代:我还需要考虑闰年。
  • 你需要实现一个专门为此设计的算法,我在快速搜索googleuWaterloo page后找到了一篇关于它的论文

标签: python pandas python-datetime


【解决方案1】:

pandas 包有一些不错的时间/日期功能。

例如

import pandas as pd
s = pd.date_range('2020-01-01', '2020-12-31', freq='D').to_series()
print(s.dt.dayofweek)

以整数形式为您提供工作日。

2020-01-01    2
2020-01-02    3
2020-01-03    4
2020-01-04    5
2020-01-05    6
2020-01-06    0
2020-01-07    1
2020-01-08    2
2020-01-09    3
2020-01-10    4

(星期一=0)

那你就可以了

mondays = s.dt.dayofweek.eq(0) 

如果您想查找一年中的第一个星期一。

print(mondays.idxmax())                                                    
Timestamp('2020-01-06 00:00:00', freq='D')

或第 5 个星期一:

n = 4                                                                           
print(s[mondays].iloc[n])                                                                
Timestamp('2020-02-03 00:00:00')

如果您的销售数据框是 df,那么要比较两个不同年份的前 5 个星期一的销售额,您可以执行以下操作:

mondays = df['Date'].dt.dayofweek.eq(0)
mondays_in_y1 = (df['Year'] == 2019) & mondays
mondays_in_y2 = (df['Year'] == 2020) & mondays 

pd.DataFrame({
    2019: df.loc[mondays_in_y1, 'Sales'].values[:5],
    2020: df.loc[mondays_in_y2, 'Sales'].values[:5]
})

【讨论】:

    【解决方案2】:

    你可以在 IIUC 上玩

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame({"date":pd.date_range(start="2020-01-01",
                                            end="2020-12-31")})
    # weekday number Monday is 0
    df["dow"] = df["date"].dt.weekday
    
    # is weekday as int
    df["is_weekday"] =  (df["dow"]<5).astype(int)
    
    df["n"] = df["is_weekday"].cumsum()
    
    # remove weekends
    df["n"] = np.where(df["n"]==df["n"].shift(), np.nan, df["n"])
    
    df[df["n"]==100]["date"]
    

    编辑 只有两行

    df["n"] = (df["date"].dt.weekday<5).astype(int).cumsum()
    df["n"] = np.where(df["n"]==df["n"].shift(), np.nan, df["n"])
    

    【讨论】:

      【解决方案3】:

      您可以尝试使用dt.week。它返回一个系列,但您可以简单地使用这些值定义一个新列。

      例如:

      import pandas as pd
      rng = pd.date_range('2015-02-24', periods=5, freq='D')
      df = pd.DataFrame({ 'Date': rng, 'Val' : np.random.randn(len(rng))})
      

      输出:

             Date        Val
      
      0   2015-02-24  -0.977278
      1   2015-02-25  0.950088
      2   2015-02-26  -0.151357
      3   2015-02-27  -0.103219
      4   2015-02-28  0.410599
      

      您应该输入df['Week_Number'] = df['Date'].dt.week,因此您将创建一个带有周数的新列:

             Date        Val     Week_Number
      
      0   2015-02-24  -0.977278   9
      1   2015-02-25   0.950088   9
      2   2015-02-26  -0.151357   9
      3   2015-02-27  -0.103219   9
      4   2015-02-28   0.410599   9
      

      希望对您有所帮助。这是我的第一个贡献。

      【讨论】:

        猜你喜欢
        • 2013-06-17
        • 1970-01-01
        • 1970-01-01
        • 2017-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-01
        • 1970-01-01
        相关资源
        最近更新 更多