Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Python(pandas)中的日期列获取周开始日期(星期一)?_Python_Date_Numpy_Pandas - Fatal编程技术网

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

从Python(pandas)中的日期列获取周开始日期(星期一)?,python,date,numpy,pandas,Python,Date,Numpy,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) 但

我已经看过很多关于如何使用日期字符串的帖子,但我正在尝试使用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['daysoffset']), axis=1)
我还没有实际测试过这段代码(没有样本数据),但这应该适用于您所描述的内容

但是,您可能想看看,这可能会提供更好的解决方案,具体取决于您正在寻找的内容。

另一种选择:

df['week_start'] = df['myday'].dt.to_period('W').apply(lambda r: r.start_time)
这会将“week_start”设置为“myday”时间之前的第一个星期一。

虽然和解决方案都有效,但我倾向于避免在Pandas中使用apply,因为与基于阵列的方法相比,它通常非常慢。为了避免这种情况,在转换为datetime列(通过
pd.to_datetime
)后,我们可以修改基于工作日的方法,并通过直接转换将一周中的某一天转换为a:

df['week_start'] = df['myday'] - df['myday'].dt.weekday.astype('timedelta64[D]')
或用作:

使用60000次datetimes的测试数据,我使用新发布的Pandas 1.0.1的建议答案获得了以下时间

%timeit df.apply(lambda x: x['myday'] - datetime.timedelta(days=x['myday'].weekday()), axis=1)
>>> 1.33 s ± 28.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit df['myday'].dt.to_period('W').apply(lambda r: r.start_time)
>>> 5.59 ms ± 138 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit df['myday'] - df['myday'].dt.weekday.astype('timedelta64[D]')
>>> 3.44 ms ± 106 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit df['myday'] - pd.to_timedelta(df['myday'].dt.weekday, unit='D')
>>> 3.47 ms ± 170 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
这些结果表明,Pandas 1.0.1显著提高了基于to_期应用的方法的速度(与Pandas相比(只是补充了Pandas的答案)

使用
.astype('timedelta64[D]')
对我来说似乎不太易懂——找到了一种仅使用pandas功能的替代方法:

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

谢谢你的解释。这个解决方案正是我想要的!如果
TimeDelta
不引用
df['daysofset']
?使用lambda会导致一些事情进展缓慢。这是怎么做的?我的数据集中的df['myday'].dt.weekday.astype('timedelta64[D])会返回一系列全零。为什么或者如何从df中减去0['myday']工作?这似乎是最好的解决方案。澄清上面的帖子,我理解发生了什么的方式是,基本上它是说取日期,然后从中减去星期几。但我不明白的是为什么。astype('timedelta64[D]”)结果全为零。@DonQuixote可能您的“myday”频率小于“1D”。这将不起作用。您必须修改它以减去小时、分钟等。我喜欢@Paul中的lambda表达式,但这个答案要快得多,同样“简洁”。谢谢您的解决方案。谢谢。
df['myday'].dt.to_period('W')).dt.start_time
可能比使用
apply
更快(不确定何时引入此功能,可能不适用于较旧版本)
df['myday'] - pd.to_timedelta(arg=df['myday'].dt.weekday, unit='D')
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)