看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
由于时间格式样式比较多,很多情况下 pandas 并不能自动识别为时间类型,所以我们在处理前的数据清洗过程中,需要专门对数据进行时间类型转换。
astype
是最简单的时间转换方法,它只能针对相对标准的时间格式,如:
s = pd.Series(['2016-01-31', '2016-02-29', '2016-03-31'])
s.astype('datetime64[ns]')
'''
0 2016-01-31
1 2016-02-29
2 2016-03-31
dtype: datetime64[ns]
'''
如果需要指定时区:
s = pd.Series(['2016-01-31', '2016-02-29', '2016-03-31'])
s.astype('datetime64[ns, US/Eastern]')
'''
0 2016-01-31 00:00:00-05:00
1 2016-02-29 00:00:00-05:00
2 2016-03-31 00:00:00-04:00
dtype: datetime64[ns, US/Eastern]
'''
# 北京时间是 Asia/Shanghai
在上文中,我们转换时间时使用的是 ns (纳秒),最大程度地保留了最细的时间颗粒的供我们未来使用,但有时间我们不需要这么精确的细小粒度,如何操作呢?这就需要在 datetime64 后的括号里指定我们想要的粒度,如:
# 一个时间文本序列
s = pd.Series(['2016-01-31 10:18:04', '2016-02-29 12:18:09'])
s
'''
0 2016-01-31 10:18:04
1 2016-02-29 12:18:09
dtype: object
'''
# 纳秒级
s.astype('datetime64[ns]')
'''
0 2016-01-31 10:18:04
1 2016-02-29 12:18:09
dtype: datetime64[ns]
'''
# 日级
s.astype('datetime64[D]')
'''
0 2016-01-31
1 2016-02-29
dtype: datetime64[ns]
'''
# 小时级
s.astype('datetime64[h]')
'''
0 2016-01-31 10:00:00
1 2016-02-29 12:00:00
dtype: datetime64[ns]
'''
# 秒级
s.astype('datetime64[s]')
'''
0 2016-01-31 10:18:04
1 2016-02-29 12:18:09
dtype: datetime64[ns]
'''
# 月级,当月第一天
s.astype('datetime64[M]')
'''
0 2016-01-01
1 2016-02-01
dtype: datetime64[ns]
'''
# 年级,当年第一天
s.astype('datetime64[Y]')
'''
0 2016-01-01
1 2016-01-01
dtype: datetime64[ns]
'''
# 周级,当周周四(原因如下)
s.astype('datetime64[W]')
'''
0 2016-01-28
1 2016-02-25
dtype: datetime64[ns]
'''
'datetime64[W]'
的结果为周四是因为这只是四舍五入,是经过设计的。括号里还可以为 2W、7D等开工,如 7D 的意思是“自纪元(1970-01-01T00:00Z )以来7D的倍数”,就像 D 的意思是“自纪元以来一天的倍数”,7D 和 W 是同义词。
我们可以看到,除了周、月、年等,其他粒度仍然以纳秒存储,不过精确度都会损失。这个规划在下边我们介绍的 pd.to_datetime()
中也适用。
在 astype
中还可以传入短字符串表示法 <M8[ns]
表示类型,M8 是 numpy.datetime64 的字符表示形式:
s.astype('M8[ns]')
s.astype('<M8[ns]')
s.astype('<M8[ns]')
s.astype('M8')
'''
0 2016-01-31 10:18:04
1 2016-02-29 12:18:09
dtype: datetime64[ns]
'''
s.astype('M8[Y]')
'''
0 2016-01-01
1 2016-01-01
dtype: datetime64[ns]
'''
s.astype('datetime64[s]').dtype
# dtype('<M8[ns]')
datetime64[ns]
是通用数据类型,而 <M8[ns]
是一个特定的数据类型。一般 dtypes 映射到特定的 dtypes,但可能会因 NumPy 的一个安装而异。
在字节顺序为小端的机器上,np.dtype('datetime64[ns]')
和 np.dtype('<M8[ns]')
两者之间没有区别 ,然而,在大端机器上,np.dtype('datetime64[ns]')
等于 np.dtype('>M8[ns]')
,所以 datetime64[ns]
映射到 <M8[ns]
或 >M8[ns]
取决于机器的字节序。还有许多其他类似的将通用数据类型映射到特定数据类型的示例:int64
映射到 <i8
或 >i
8 , 和 int
映射到 int32
或 int64
取决于操作系统的位架构以及 NumPy 的编译方式。
详见:NumPy 的数据类型
Pandas 提供的 pd.to_datetime()
是识别转换时间的主要工具。接下来我们看一些例子。
从 DataFrame 的多个列中组合一个日期时间。 键可以是常见的缩写,例如['year','month','day','minute','second','ms','us','ns']):
df = pd.DataFrame({'year': [2015, 2016],
'month': [2, 3],
'day': [4, 5]})
df
'''
year month day
0 2015 2 4
1 2016 3 5
'''
pd.to_datetime(df)
pd.to_datetime(df[['year', 'month', 'day']]) # 同上
'''
0 2015-02-04
1 2016-03-05
dtype: datetime64[ns]
'''
智能解析时间:
pd.to_datetime(pd.Series(['Jul 31, 2009', '2010-01-10', None]))
'''
0 2009-07-31
1 2010-01-10
2 NaT
dtype: datetime64[ns]
'''
pd.to_datetime(['2005/11/23', '2010.12.31'])
# DatetimeIndex(['2005-11-23', '2010-12-31'], dtype='datetime64[ns]', freq=None)
pd.to_datetime(['04-01-2012 10:00'], dayfirst=True) # 日期在前
# DatetimeIndex(['2012-01-04 10:00:00'], dtype='datetime64[ns]', freq=None)
可以使用 pd.Timestamp()
进行转换:
pd.to_datetime('2010/11/12')
# Timestamp('2010-11-12 00:00:00')
pd.Timestamp('2010/11/12')
# Timestamp('2010-11-12 00:00:00')
pd.DatetimeIndex
也可以转换:
pd.DatetimeIndex(['2018-01-01', '2018-01-03', '2018-01-05'])
# DatetimeIndex(['2018-01-01', '2018-01-03', '2018-01-05'], dtype='datetime64[ns]', freq=None)
pd.DatetimeIndex(['2018-01-01', '2018-01-03', '2018-01-05'], freq='infer')
# DatetimeIndex(['2018-01-01', '2018-01-03', '2018-01-05'], dtype='datetime64[ns]', freq='2D')
对于有格式的数据,需要指定数据的格式:
pd.to_datetime('13000101', format='%Y%m%d', errors='ignore')
# 可以让系统自己推断时间格式
pd.to_datetime('13000101', infer_datetime_format=True, errors='ignore')
# datetime.datetime(1300, 1, 1, 0, 0)
# coerce 将不会忽略错误,返回空值
pd.to_datetime('13000101', format='%Y%m%d', errors='coerce')
# NaT
# 有时间需要字段转为字符
pd.to_datetime(df.d.astype(str), format='%m/%d/%Y')
# 其他
pd.to_datetime('2010/11/12', format='%Y/%m/%d')
# Timestamp('2010-11-12 00:00:00')
pd.to_datetime('12-11-2010 00:00', format='%d-%m-%Y %H:%M')
# Timestamp('2010-11-12 00:00:00')
对时间戳进行转换,需要给出时间单位,一般为秒:
pd.to_datetime(1490195805, unit='s')
# Timestamp('2017-03-22 15:16:45')
pd.to_datetime(1490195805433502912, unit='ns')
# Timestamp('2017-03-22 15:16:45.433502912')
对周期数据进行转换:
pd.to_datetime([1, 2, 3], unit='D',
origin=pd.Timestamp('1960-01-01'))
# DatetimeIndex(['1960-01-02', '1960-01-03', '1960-01-04'], dtype='datetime64[ns]', freq=None)
python中时间日期格式化符号:
更新时间:2024-05-22 11:55:47 标签:pandas 时间 数据类型