Получить начальную дату недели (понедельник) из столбца даты в Python (pandas)?

Я видел много сообщений о том, как вы можете это сделать с помощью строки даты, но я пытаюсь что-то сделать для столбца dataframe и пока не получил никакой удачи. Мой текущий метод: получить будний день с «myday», а затем компенсировать, чтобы получить понедельник.

df['myday'] is column of dates. mydays = pd.DatetimeIndex(df['myday']).weekday df['week_start'] = pd.DatetimeIndex(df['myday']) - pd.DateOffset(days=mydays) 

Но я получаю TypeError: неподдерживаемый тип для компонента timedelta days: numpy.ndarray

Как я могу получить дату начала недели из столбца df?

он терпит неудачу, потому что pd.DateOffset ожидает единственное целое число в качестве параметра (и вы кормите его массивом). Вы можете использовать DateOffset только для изменения столбца даты тем же самым смещением.

попробуй это :

 import datetime as dt # Change 'myday' to contains dates as datetime objects df['myday'] = pd.to_datetime(df['myday']) # 'daysoffset' will container the weekday, as integers df['daysoffset'] = df['myday'].apply(lambda x: x.weekday()) # We apply, row by row (axis=1) a timedelta operation df['week_start'] = df.apply(lambda x: x['myday'] - dt.TimeDelta(days=x['mydays']), axis=1) 

Я на самом деле не тестировал этот код (не было никаких выборочных данных), но это должно работать для того, что вы описали.

Однако вы можете посмотреть на pandas.Resample , который может обеспечить лучшее решение – в зависимости от того, что вы ищете.

Другая альтернатива:

 df['week_start'] = df['myday'].dt.to_period('W').apply(lambda r: r.start_time) 

Это установит «week_start» в первый понедельник перед временем в «myday».

Хотя оба вышеупомянутых решения работают, я стараюсь избегать использования приложения в Pandas, потому что он обычно довольно медленный по сравнению с методами на основе массивов. Чтобы этого избежать, мы можем изменить метод, основанный на будничном режиме, и просто наложить день недели на число numedelta64 [D] .

 df['myday'] - df['myday'].dt.weekday.astype('timedelta64[D]') 

Используя мои тестовые данные с 60 000 датами, я получил следующее время, используя два других предложенных ответа и метод на основе литья.

 %timeit df.apply(lambda x: x['myday'] - datetime.timedelta(days=x['myday'].weekday()), axis=1) >>> 1 loop, best of 3: 7.43 s per loop %timeit df['myday'].dt.to_period('W').apply(lambda r: r.start_time) >>> 1 loop, best of 3: 2.38 s per loop %timeit df['myday'] - df['myday'].dt.weekday.astype('timedelta64[D]') >>> 100 loops, best of 3: 12.3 ms per loop 

или почти в 200 раз быстрее на моем наборе данных.