在 pandas 中提取日期时间类型列的月份的第一天 [英] Extracting the first day of month of a datetime type column in pandas
问题描述
我有以下数据框:
user_id purchase_date
1 2015-01-23 14:05:21
2 2015-02-05 05:07:30
3 2015-02-18 17:08:51
4 2015-03-21 17:07:30
5 2015-03-11 18:32:56
6 2015-03-03 11:02:30
和purchase_date
是datetime64[ns]
列.我需要添加一个新列df[month]
,其中包含购买日期所在月份的第一天:
and purchase_date
is a datetime64[ns]
column. I need to add a new column df[month]
that contains first day of the month of the purchase date:
df['month']
2015-01-01
2015-02-01
2015-02-01
2015-03-01
2015-03-01
2015-03-01
我正在寻找SQL中的DATE_FORMAT(purchase_date, "%Y-%m-01") m
之类的东西.我尝试了以下代码:
I'm looking for something like DATE_FORMAT(purchase_date, "%Y-%m-01") m
in SQL. I have tried the following code:
df['month']=df['purchase_date'].apply(lambda x : x.replace(day=1))
它以某种方式工作,但返回:2015-01-01 14:05:21
.
It works somehow but returns: 2015-01-01 14:05:21
.
推荐答案
Simpliest and fastest is convert to numpy array
by values
and then cast:
df['month'] = df['purchase_date'].values.astype('datetime64[M]')
print (df)
user_id purchase_date month
0 1 2015-01-23 14:05:21 2015-01-01
1 2 2015-02-05 05:07:30 2015-02-01
2 3 2015-02-18 17:08:51 2015-02-01
3 4 2015-03-21 17:07:30 2015-03-01
4 5 2015-03-11 18:32:56 2015-03-01
5 6 2015-03-03 11:02:30 2015-03-01
使用 floor
和pd.offsets.MonthBegin(0)
:
df['month'] = df['purchase_date'].dt.floor('d') - pd.offsets.MonthBegin(1)
print (df)
user_id purchase_date month
0 1 2015-01-23 14:05:21 2015-01-01
1 2 2015-02-05 05:07:30 2015-02-01
2 3 2015-02-18 17:08:51 2015-02-01
3 4 2015-03-21 17:07:30 2015-03-01
4 5 2015-03-11 18:32:56 2015-03-01
5 6 2015-03-03 11:02:30 2015-03-01
df['month'] = (df['purchase_date'] - pd.offsets.MonthBegin(1)).dt.floor('d')
print (df)
user_id purchase_date month
0 1 2015-01-23 14:05:21 2015-01-01
1 2 2015-02-05 05:07:30 2015-02-01
2 3 2015-02-18 17:08:51 2015-02-01
3 4 2015-03-21 17:07:30 2015-03-01
4 5 2015-03-11 18:32:56 2015-03-01
5 6 2015-03-03 11:02:30 2015-03-01
最后一个解决方案是通过创建的month period
to_period
:
Last solution is create month period
by to_period
:
df['month'] = df['purchase_date'].dt.to_period('M')
print (df)
user_id purchase_date month
0 1 2015-01-23 14:05:21 2015-01
1 2 2015-02-05 05:07:30 2015-02
2 3 2015-02-18 17:08:51 2015-02
3 4 2015-03-21 17:07:30 2015-03
4 5 2015-03-11 18:32:56 2015-03
5 6 2015-03-03 11:02:30 2015-03
...,然后通过 to_timestamp
,但速度较慢:
... and then to datetimes
by to_timestamp
, but it is a bit slowier:
df['month'] = df['purchase_date'].dt.to_period('M').dt.to_timestamp()
print (df)
user_id purchase_date month
0 1 2015-01-23 14:05:21 2015-01-01
1 2 2015-02-05 05:07:30 2015-02-01
2 3 2015-02-18 17:08:51 2015-02-01
3 4 2015-03-21 17:07:30 2015-03-01
4 5 2015-03-11 18:32:56 2015-03-01
5 6 2015-03-03 11:02:30 2015-03-01
有很多解决方案,所以:
There are many solutions, so:
时间:
rng = pd.date_range('1980-04-03 15:41:12', periods=100000, freq='20H')
df = pd.DataFrame({'purchase_date': rng})
print (df.head())
In [300]: %timeit df['month1'] = df['purchase_date'].values.astype('datetime64[M]')
100 loops, best of 3: 9.2 ms per loop
In [301]: %timeit df['month2'] = df['purchase_date'].dt.floor('d') - pd.offsets.MonthBegin(1)
100 loops, best of 3: 15.9 ms per loop
In [302]: %timeit df['month3'] = (df['purchase_date'] - pd.offsets.MonthBegin(1)).dt.floor('d')
100 loops, best of 3: 12.8 ms per loop
In [303]: %timeit df['month4'] = df['purchase_date'].dt.to_period('M').dt.to_timestamp()
1 loop, best of 3: 399 ms per loop
#MaxU solution
In [304]: %timeit df['month5'] = df['purchase_date'].dt.normalize() - pd.offsets.MonthBegin(1)
10 loops, best of 3: 24.9 ms per loop
#MaxU solution 2
In [305]: %timeit df['month'] = df['purchase_date'] - pd.offsets.MonthBegin(1, normalize=True)
10 loops, best of 3: 28.9 ms per loop
#Wen solution
In [306]: %timeit df['month6']= pd.to_datetime(df.purchase_date.astype(str).str[0:7]+'-01')
1 loop, best of 3: 214 ms per loop
这篇关于在 pandas 中提取日期时间类型列的月份的第一天的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!