我编写了一个将pandas日期时间日期转换为月末日期的函数:
import pandas
import numpy
import datetime
from pandas.tseries.offsets import Day, MonthEnd
def get_month_end(d):
month_end = d - Day() + MonthEnd()
if month_end.month == d.month:
return month_end # 31/March + MonthEnd() returns 30/April
else:
print "Something went wrong while converting dates to EOM: " + d + " was converted to " + month_end
raise
这个功能似乎很慢,我想知道是否有更快的替代方案?我注意到它很慢的原因是我在一个具有50'000个日期的数据帧列上运行它,我可以看到自引入该函数以来代码慢得多(在我将日期转换为月末之前)。
df = pandas.read_csv(inpath, na_values = nas, converters = {open_date: read_as_date})
df[open_date] = df[open_date].apply(get_month_end)
我不确定这是否相关,但我正在阅读以下日期:
def read_as_date(x):
return datetime.datetime.strptime(x, fmt)
答案 0 :(得分:30)
修改后,转换为句点然后再回到时间戳就行了
In [104]: df = DataFrame(dict(date = [Timestamp('20130101'),Timestamp('20130131'),Timestamp('20130331'),Timestamp('20130330')],value=randn(4))).set_index('date')
In [105]: df
Out[105]:
value
date
2013-01-01 -0.346980
2013-01-31 1.954909
2013-03-31 -0.505037
2013-03-30 2.545073
In [106]: df.index = df.index.to_period('M').to_timestamp('M')
In [107]: df
Out[107]:
value
2013-01-31 -0.346980
2013-01-31 1.954909
2013-03-31 -0.505037
2013-03-31 2.545073
请注意,这种类型的转换也可以像这样完成,但上面会稍快一些。
In [85]: df.index + pd.offsets.MonthEnd(0)
Out[85]: DatetimeIndex(['2013-01-31', '2013-01-31', '2013-03-31', '2013-03-31'], dtype='datetime64[ns]', name=u'date', freq=None, tz=None)
答案 1 :(得分:1)
你也可以使用numpy更快地完成它:
import numpy as np
date_array = np.array(['2013-01-01', '2013-01-15', '2013-01-30']).astype('datetime64[ns]')
month_start_date = date_array.astype('datetime64[M]')
答案 2 :(得分:1)
如果日期不在index
中,而是在另一列中(适用于Pandas 0.25.0):
import pandas as pd
import numpy as np
df = pd.DataFrame(dict(date = [pd.Timestamp('20130101'),
pd.Timestamp('20130201'),
pd.Timestamp('20130301'),
pd.Timestamp('20130401')],
value = np.random.rand(4)))
print(df.to_string())
df.date = df.date.dt.to_period('M').dt.to_timestamp('M')
print(df.to_string())
输出:
date value
0 2013-01-01 0.295791
1 2013-02-01 0.278883
2 2013-03-01 0.708943
3 2013-04-01 0.483467
date value
0 2013-01-31 0.295791
1 2013-02-28 0.278883
2 2013-03-31 0.708943
3 2013-04-30 0.483467
答案 3 :(得分:0)
如果日期列采用datetime格式并设置为每月的开始日期,则会为其增加一个月的时间:
df['date1']=df['date'] + pd.offsets.MonthEnd(0)
答案 4 :(得分:0)
您正在寻找的可能是:
df.resample('M')。last()
@Jeff先前所说的另一种方法:
df.index = df.index.to_period('M')。to_timestamp('M')