从Pandas Datetime列中单独提取月份和年份
我有一个数据框,叫做 df
,里面有以下一列:
ArrivalDate
936 2012-12-31
938 2012-12-29
965 2012-12-31
966 2012-12-31
967 2012-12-31
968 2012-12-31
969 2012-12-31
970 2012-12-29
971 2012-12-31
972 2012-12-29
973 2012-12-29
这一列的元素是 pandas.tslib.Timestamp
类型。我想提取出年份和月份。
我尝试过的方法是:
df['ArrivalDate'].resample('M', how = 'mean')
但是出现了以下错误:
Only valid with DatetimeIndex or PeriodIndex
然后我又试了:
df['ArrivalDate'].apply(lambda(x):x[:-2])
结果又出现了以下错误:
'Timestamp' object has no attribute '__getitem__'
我现在的解决方案是:
df.index = df['ArrivalDate']
接着,我可以利用索引对另一列进行重采样。
不过我还是想要一个方法来重新配置整列数据。有没有什么好主意?
11 个回答
单行操作:添加一个包含'年-月'对的列:
('pd.to_datetime' 首先将列的数据类型转换为日期时间,然后再进行操作)df['yyyy-mm'] = pd.to_datetime(df['ArrivalDate']).dt.strftime('%Y-%m')
如果你想额外添加一个'年'或'月'的列,可以这样做:
df['yyyy'] = pd.to_datetime(df['ArrivalDate']).dt.strftime('%Y')
df['mm'] = pd.to_datetime(df['ArrivalDate']).dt.strftime('%m')
如果你想要得到独特的“月份-年份”组合,使用apply这个方法非常简单好用。
df['mnth_yr'] = df['date_column'].apply(lambda x: x.strftime('%B-%Y'))
这样可以把“月份-年份”放在同一列里。
别忘了在此之前先把格式改成日期时间,我一般都会忘记这一步。
df['date_column'] = pd.to_datetime(df['date_column'])
你可以直接访问 year
(年份)和 month
(月份)这两个属性,或者请求一个 datetime.datetime
对象:
In [15]: t = pandas.tslib.Timestamp.now()
In [16]: t
Out[16]: Timestamp('2014-08-05 14:49:39.643701', tz=None)
In [17]: t.to_pydatetime() #datetime method is deprecated
Out[17]: datetime.datetime(2014, 8, 5, 14, 49, 39, 643701)
In [18]: t.day
Out[18]: 5
In [19]: t.month
Out[19]: 8
In [20]: t.year
Out[20]: 2014
将年份和月份结合起来的一种方法是把它们编码成一个整数,比如:201408
代表2014年8月。你可以在整列数据中这样做:
df['YearMonth'] = df['ArrivalDate'].map(lambda x: 100*x.year + x.month)
或者有很多其他的变体。
不过,我个人不太喜欢这样做,因为这样会让后面对日期的对齐和计算变得很麻烦,尤其是对于那些没有遵循这个约定的人来说,理解你的代码或数据会更加困难。更好的方法是选择一个具体的日期约定,比如选择一个月的最后一个非美国假日的工作日,或者选择一个月的第一天等等,然后把数据保留在日期/时间的格式中,使用你选择的日期约定。
calendar
模块很有用,可以用来获取某些特定日期的数值,比如最后一个工作日。然后你可以这样做:
import calendar
import datetime
df['AdjustedDateToEndOfMonth'] = df['ArrivalDate'].map(
lambda x: datetime.datetime(
x.year,
x.month,
max(calendar.monthcalendar(x.year, x.month)[-1][:5])
)
)
如果你只是想把日期时间列格式化成某种字符串表示形式,你可以使用 strftime
函数,这个函数来自 datetime.datetime
类,可以这样使用:
In [5]: df
Out[5]:
date_time
0 2014-10-17 22:00:03
In [6]: df.date_time
Out[6]:
0 2014-10-17 22:00:03
Name: date_time, dtype: datetime64[ns]
In [7]: df.date_time.map(lambda x: x.strftime('%Y-%m-%d'))
Out[7]:
0 2014-10-17
Name: date_time, dtype: object
df['date_column']
这一列的数据必须是日期时间格式。
df['month_year'] = df['date_column'].dt.to_period('M')
你还可以用 D
表示天,2M
表示两个月等等,来设置不同的采样间隔。如果你有带时间戳的时间序列数据,可以选择更细的采样间隔,比如 45Min
表示45分钟,15Min
表示15分钟采样等等。
如果你想要新增加的列分别显示年份和月份,你可以这样做:
df['year'] = pd.DatetimeIndex(df['ArrivalDate']).year
df['month'] = pd.DatetimeIndex(df['ArrivalDate']).month
或者……
df['year'] = df['ArrivalDate'].dt.year
df['month'] = df['ArrivalDate'].dt.month
然后你可以把它们合并在一起,或者直接使用它们。