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

时间:2015-01-16 17:07:41

标签: python date numpy 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)

但我明白了 TypeError:timedelta days组件的不支持类型:numpy.ndarray

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

5 个答案:

答案 0 :(得分:21)

另一种选择:

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

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

答案 1 :(得分:11)

虽然@knightofni's@Paul's解决方案都有效,但我倾向于避免在Pandas中使用apply,因为与基于数组的方法相比,它通常很慢。为了避免这种情况,我们可以修改基于工作日的方法,只需将星期几转换为numpy timedelta64[D]

df['week_start'] = 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倍。

答案 2 :(得分:2)

(只需添加n8yoder的答案)

使用.astype('timedelta64[D]')似乎对我来说不太可读 - 只使用pandas的功能找到了另一种选择:

df['myday'] - pd.to_timedelta(arg=df['myday'].dt.weekday, unit='D')

答案 3 :(得分:1)

它失败了,因为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,这可能会提供更好的解决方案 - 具体取决于您要查找的内容。

答案 4 :(得分:0)

from datetime import datetime, timedelta

# Convert column to pandas datetime equivalent
df['myday'] = pd.to_datetime(df['myday']) 

# Create function to calculate Start Week date
week_start_date = lambda date: date - timedelta(days=date.weekday())

# Apply above function on DataFrame column
df['week_start_date'] = df['myday'].apply(week_start_date)