Как я могу рассчитать неделю месяца из недели года? - PullRequest
3 голосов
/ 13 апреля 2019

Я нашел решение 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
 .   .      .        .      .
 .   .      .        .      .
 .   .      .        .      .

Ответы [ 2 ]

0 голосов
/ 15 апреля 2019

Я нашел относительно длинное и уродливое решение, которое, кажется, работает.Если есть ошибки / ошибки или более чистая реализация, дайте мне знать.

Мой подход : на примере 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
Получайте каждую неделю в течение года, с которым вы имеете дело.В нашем примере это 2011

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

Этот код извлекает год и сохраняет его в 4-мерном списке: month-junk (в нашем случае это 1 мусор12 месяцев), месяц, неделя, день.Для запроса сделайте что-то вроде yr[0][6][4][:] для всех дней 5-й недели июля.По этой причине следующим шагом будет преобразование его в двумерный массив, содержащий все недели.

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

Этот dates будет содержать дубликаты, поскольку cal.yeardatescalendar() возвращает список.Мы удалим их:

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])

На данный момент у вас есть двумерный массив недель, который соответствует номерам ваших недель.Например, если вы перейдете сюда и проверите неделю 30 для 2011, вы увидите, что это 5-я неделя июля.

Далее, мы используем «правильный» массив списка недель для запроса нашей недели.Ex.неделя 30

the_week = new_dates[:][30]

Наконец, мы видим, какая неделя является нашей неделей в месяце.Когда мы получаем совпадение, мы знаем, что это номер недели.
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)

0 голосов
/ 13 апреля 2019

Мы можем сделать следующее:

Сначала мы конвертируем Year + Week в дату и время, используя pandas.to_datetime

from datetime import datetime as dt

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

Затем мы определяем функцию какупоминается в комментариях от здесь :

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% точно, если бы у нас были точные даты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...