【问题标题】:How can I calculate the week of the month from week of the year?如何从一年中的一周计算一个月的一周?
【发布时间】:2019-09-04 04:09:02
【问题描述】:

我找到了node.js 解决方案,但找不到 python 解决方案。我有一个DataFrame,看起来像:

   Year  Month      Week  numOfTrips
0  2011  July       30    2608
1  2011  August     31    6852
2  2011  August     32    8092
3  2011  August     33    7674
4  2011  August     34    7065
5  2011  August     35    3896
6  2011  September  35    4182
7  2011  September  36    7315
8  2011  September  37    8929
9  2011  September  38    7822
10 2011  September  39    6508
11 2011  October    39    1848
12 2011  October    40    9233
13 2011  October    41    7818
14 2011  October    42    7627
 .   .      .        .      .
 .   .      .        .      .
 .   .      .        .      .

我想用当月的周数替换每个周数,我该怎么做?

结果如下:

   Year  Month      Week  numOfTrips
0  2011  July       5     2608
1  2011  August     1     6852
2  2011  August     2     8092
3  2011  August     3     7674
4  2011  August     4     7065
5  2011  August     5     3896
6  2011  September  1     4182
7  2011  September  2    7315
8  2011  September  3    8929
9  2011  September  4    7822
10 2011  September  5    6508
11 2011  October    1    1848
12 2011  October    2    9233
13 2011  October    3    7818
14 2011  October    4    7627
 .   .      .        .      .
 .   .      .        .      .
 .   .      .        .      .

【问题讨论】:

  • 将您的数据转换为date 对象,然后查看此答案:stackoverflow.com/questions/3806473/…
  • @DroidX86 你的意思是datetime?如df['Week'] = pd.to_datetime(df.Week) ?
  • 是的,试试吧。获取日期信息的最佳方法是使用实​​际的 datetime 对象。
  • 对于仍在试图解决这个问题的人(比如我):这些周数是“一年中的第几周”,由Series.dt.week返回

标签: python pandas date calendar time-series


【解决方案1】:

我们可以做到以下几点:

首先,我们使用 pandas.to_datetime 将您的 Year + Week 转换为日期时间

from datetime import datetime as dt

df['Date'] = pd.to_datetime(df['Year'].astype(str) + '-' + df['Week'].astype(str) + '-1', format='%Y-%W-%w')

然后我们定义here的cmets中提到的函数:

from math import ceil

def week_of_month(dt):
    """ Returns the week of the month for the specified date.
    """

    first_day = dt.replace(day=1)

    dom = dt.day
    adjusted_dom = dom + first_day.weekday()

    return int(ceil(adjusted_dom/7.0))

最后,我们将函数应用到我们的Date 列以获取月份的Weeknumber

df['Week'] = df['Date'].apply(week_of_month)

产量:

print(df)
   Year      Month  Week  numOfTrips       Date
0  2011       July     5        2608 2011-07-25
1  2011     August     1        6852 2011-08-01
2  2011     August     2        8092 2011-08-08
3  2011     August     3        7674 2011-08-15
4  2011     August     4        7065 2011-08-22
5  2011     August     5        3896 2011-08-29
6  2011  September     5        4182 2011-08-29

注意它不是 100% 准确的最后一行,因为你没有准确的日期。如果我们有准确的日期,这将是 100% 准确的。

【讨论】:

  • 确切日期是什么意思?如果 9 月 39 周也是第 5 周,则 2011 年 9 月的第 35 周不能是第 5 周...
  • 我们从Year + Week 中提取了Date 列。如您所见,我们的Date 列只能在周级别上准确,而不是在日级别上。这就是为什么它给第 5 行和第 6 行指定相同的日期。
  • 好的,我将您的评论解释为我没有足够的数据来进行准确的计算。在等式中使用Month 我应该能够得到正确的星期。这就是现在正在尝试的。
  • 你看我的回答了吗?那么你可能会更好地理解我的意思
【解决方案2】:

我找到了一个相对冗长且丑陋的解决方案,似乎可行。如果有错误/错误或更简洁的实现,请告诉我。

我的方法:使用示例2011 July 30 2608

  1. 获取相应月份相应年份的周数
m = list(calendar.month_name).index('July') # turn month name into int
cal = calendar.Calendar()
weeks = cal.monthdatescalendar(2011,7) # get weeks for that month in the year
  1. 获取您正在处理的一年中的每个星期。在我们的示例中,它的 2011

yr = cal.yeardatescalendar(2011, width=12)

此代码将获取年份并将其存储在 4D 列表中:month-junk(在我们的例子中是 12 个月的 1 个垃圾)、月、周、日。要查询,请在 7 月的第 5 周的所有日子里执行yr[0][6][4][:] 之类的操作。正因为如此,下一步就是把它变成一个二维数组来保存所有的星期。

flat = [week for month in yr[0] for week in month]
dates = np.array(flat)

由于cal.yeardatescalendar() 返回列表的方式,此dates 将包含重复项。我们删除了这些:

new_dates = []
for date in range(len(dates)):
    if not(np.array_equal(dates[date], np.array(dates[date-1]))):
        new_dates.append(dates[date])

此时,您有一个与您的周数一致的 2D 周数组。就像如果你去here,检查周30 是否有2011,你会看到它是7 月的第5 周。

  1. 接下来,我们使用“正确的”周列表数组来查询我们的周。前任。周30

the_week = new_dates[:][30]

  1. 最后,我们会看到一个月中的哪一周。当我们得到匹配时,我们知道它是那个周数。
for week in range(len(weeks)): 
    if np.array_equal(the_week, np.array(weeks[week])):
        save_week_num = week+1
        print(save_week_num) # for our example it will print 5

这是在一个函数中:

def week_of_month(year, month, y_week):
    m = list(calendar.month_name).index(month) 
    cal = calendar.Calendar()
    weeks = cal.monthdatescalendar(year,m) 

    yr = cal.yeardatescalendar(year, width=12)
    flat = [week for month in yr[0] for week in month]
    dates = np.array(flat)

    new_dates = []
    for date in range(len(dates)):
        if not(np.array_equal(dates[date], np.array(dates[date-1]))):
            new_dates.append(dates[date])

    the_week = new_dates[:][y_week] # for 2013, replace this with: the_week = new_dates[:][y_week-1] 

    number = 0
    for week in range(len(weeks)):

        if np.array_equal(the_week, np.array(weeks[week])):

            save_week_num = week+1
            number = save_week_num

    return number

要在问题运行中的DataFrame 上对其进行测试:

df['Week'] = df.apply(lambda row: week_of_month(row.Year, row.Month, row.Week), axis=1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    • 2015-05-05
    • 2016-02-12
    相关资源
    最近更新 更多