Получите первый день недели для серии Pandas - PullRequest
0 голосов
/ 06 июля 2018

У меня есть следующий df:

import pandas as pd
from datetime import datetime, timedelta

df = pd.DataFrame([
        ["A", "2018-08-03"],
        ["B", "2018-08-20"]
])
df.columns = ["Item", "Date"]

Я хочу получить первый день недели для каждой строки моего df. Я пытался сделать это:

df['Date'] =  pd.to_datetime(df['Date'], format='%Y-%m-%d')
df["Day_of_Week"] = df.Date.dt.weekday

df["First_day_of_the_week"] = df.Date - timedelta(days=df.Day_of_Week)

Но я получил это сообщение об ошибке:

TypeError: unsupported type for timedelta days component: Series

Как я могу получить первый день недели для серии? Мой ожидаемый результат таков:

  • «А», «2018-08-03», «2018-07-30»
  • "B", "2018-08-20", "2018-08-20"

Ответы [ 5 ]

0 голосов
/ 14 октября 2018

pandas версия

df = pd.DataFrame({
    'Item': ['A', 'B'],
    'Date': ['2018-08-03', '2018-08-20']
})

df['Date'] = pd.to_datetime(df.Date) #Use pd.Timestamp
df.Date - pd.TimedeltaIndex(df.Date.dt.dayofweek,unit='d') 

Выход:

0   2018-07-30
1   2018-08-20
dtype: datetime64[ns]

Документы об используемых функциях: pd.TimedeltaIndex , pd.to_datetime

Работа с датой и временем: Функциональность временных рядов / даты

0 голосов
/ 06 июля 2018

Вы можете остаться в Пандах и использовать DateOffset объектов:

>>> from pandas.tseries.offsets import Week

>>> df.Date.where(df.Date.dt.weekday == 0, df.Date - Week(weekday=0))
0   2018-07-30
1   2018-08-20
Name: Date, dtype: datetime64[ns]

Хитрость в том, что вам не нужно делать вычитание, когда день недели уже понедельник (день недели == 0). Это говорит: «В тех случаях, когда день недели уже равен нулю, ничего не делайте; в противном случае верните понедельник этой недели».

0 голосов
/ 06 июля 2018

Оставьте свой расчет "День недели" и сделайте это.

df["First_day_of_the_week"] = df['Date'].apply(lambda x: (x - timedelta(days=x.dayofweek)))
print(df)

давая

  Item       Date First_day_of_the_week
0    A 2018-08-03            2018-07-30
1    B 2018-08-20            2018-08-20
0 голосов
/ 06 июля 2018

Векторизованное решение возможно с NumPy:

df['First_day'] = df['Date'] - df['Date'].dt.weekday * np.timedelta64(1, 'D')

print(df)

  Item       Date  First_day
0    A 2018-08-03 2018-07-30
1    B 2018-08-20 2018-08-20
0 голосов
/ 06 июля 2018

К сожалению timedelta не поддерживает векторизованную форму, поэтому я бы выбрал apply

df["First_day_of_the_week"] = df.apply(lambda x: x['Date'] - timedelta(days=x['Day_of_Week']), axis=1)

EDIT

timedelta не поддерживает векторизованные аргументы, но может быть умножен на вектор:)

df["First_day_of_the_week"] = df.Date - df.Day_of_Week * timedelta(days=1)
...