Я нашел относительно длинное и уродливое решение, которое, кажется, работает.Если есть ошибки / ошибки или более чистая реализация, дайте мне знать.
Мой подход : на примере 2011 July 30 2608
- Получите недели для соответствующегомесяц в соответствующем году
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)