从Python(pandas)的日期列中获取周开始日期(星期一)?

dev*_*v28 16 python numpy date pandas

我已经看过很多关于你如何使用日期字符串的帖子,但我正在为数据帧列尝试一些东西,到目前为止还没有运气.我目前的方法是:从'myday'获取工作日,然后偏移以获得星期一.

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

但我得到TypeError:timedelta days组件的不支持类型:numpy.ndarray

如何从df列获取周开始日期?

Pau*_*aul 23

另一种选择:

df['week_start'] = df['myday'].dt.to_period('W').apply(lambda r: r.start_time)
Run Code Online (Sandbox Code Playgroud)

这将把'week_start'设置为'myday'之前的第一个星期一.

  • 谢谢你。`df['myday'].dt.to_period('W').dt.start_time` 可能比使用 `apply` 更快(不确定何时引入,可能不适用于较旧的 pandas 版本) (7认同)
  • 可以设置任意一天以[锚定偏移量](https://pandas.pydata.org/docs/user_guide/timeseries.html#anchored-offsets)开始一周。周日开始时间为“W-SUN”或周四开始时间为“W-THU”。 (3认同)

n8y*_*der 17

虽然上述两种解决方案都有效,但我倾向于避免在Pandas中使用apply,因为与基于数组的方法相比,它通常很慢.为了避免这种情况,我们可以修改基于工作日的方法,并简单地将星期几投射为numpy timedelta64 [D].

df['week_start'] = df['myday'] - df['myday'].dt.weekday.astype('timedelta64[D]')
Run Code Online (Sandbox Code Playgroud)

使用我的测试数据和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
Run Code Online (Sandbox Code Playgroud)

或者我的数据集快了近200倍.


rib*_*iyb 11

(只是添加到n8yoder的答案)

使用.astype('timedelta64[D]')对我来说似乎不太可读——找到了一个只使用熊猫功能的替代方案:

df['myday'] - pd.to_timedelta(arg=df['myday'].dt.weekday, unit='D')
Run Code Online (Sandbox Code Playgroud)


kni*_*fni 10

它失败是因为 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['daysoffset']), axis=1)
Run Code Online (Sandbox Code Playgroud)

我还没有真正测试过这段代码,(没有样本数据),但这应该适用于你所描述的。

但是,您可能想查看pandas.Resample,它可能会提供更好的解决方案 - 取决于您正在寻找的内容。