将字符串转换为日期作为datetime对象

使用日期和时间来分析数据集通常很麻烦。你可以根据自己的情况考虑不同长度的月份, 工作日和周末的不同分布, leap年和可怕的时区。因此, Python具有专门为日期和时间设计的数据类型, 称为datetime。
但是, 在许多数据集中, 你会发现日期以字符串表示。因此, 在本教程中, 你将学习如何将日期字符串转换为datetime格式, 并了解如何使用其功能强大的工具有效处理复杂的时间序列数据。
处理日期的不同表示
【将字符串转换为日期作为datetime对象】主要挑战通常是指定如何表达日期字符串。例如, ” 2018年6月6日星期三” 也可以表示为” 6/6/18″ 和” 06-06-2018″ 。这些都通知你相同的日期, 但是你可能可以想象, 转换每个日期的代码略有不同。花点时间检查下面的函数调用:

from datetime import datetime# Define dates as stringsdate_str1 = 'Wednesday, June 6, 2018'date_str2 = '6/6/18'date_str3 = '06-06-2018'# Define dates as datetime objectsdate_dt1 = datetime.strptime(date_str1, '%A, %B %d, %Y')date_dt2 = datetime.strptime(date_str2, '%m/%d/%y')date_dt3 = datetime.strptime(date_str3, '%m-%d-%Y')# Print converted datesprint(date_dt1)print(date_dt2)print(date_dt3)

2018-06-06 00:00:002018-06-06 00:00:002018-06-06 00:00:00

首先, 从datetime模块导入datetime类型。然后, 日期字符串将传递给.strptime()方法, 然后传递给Python的strptime指令。你可以结合使用伪指令, 特殊字符(例如, 在上述情况下为、、 /或-)和空格, 以匹配你要解析的日期字符串。如你所见, 由于所有三个日期字符串都表示相同的日期, 因此生成的datetime对象是相同的。
你可以在Python文档中找到指令的完整列表, 但下表是与你在上方看到的最相关的表:
代码 含义 例子
%A 工作日为语言环境的全名。 星期三
%a 工作日为语言环境的缩写名称。 星期三
%B 月份作为语言环境的全名。 六月
%d 一个月中的某天。 06
%m 以数字表示的月份。 6
%Y 四位数的年份。 2018
%y 两位数的年份。 18
转换日期字符串列
现在你已经熟悉了Python的strptime指令, 让我们学习如何将数据集中的整个日期字符串列转换为datetime格式。
从现在开始, 你将使用一个名为eth的数据框架, 其中包含有关以太坊的一些历史数据, 这是一种加密货币, 其区块链由以太坊平台生成。你的数据集包含以下列:
  • 日期:日期, 每天世界标准时间00:00。
  • txVolume:未经调整的度量值, 以美元为单位, 表示区块链上的输出。
  • txCount:在公共区块链上发生的交易数量。
  • marketCap:以美元为单位的价格乘以流通的单位数。
  • 价格:UTC 00:00的美元开盘价。
  • generateCoins:已被开采的新硬币数量。
  • exchangeVolume:GDAX和Bitfinex等交易所的交易量, 以美元为单位。
这是数据集的前几行。请注意日期的表示方式, 以便以后可以使用正确的指令:
print(eth.head())

datetxVolume(USD)txCountmarketcap(USD)price(USD)\02015-08-101.193012e+06203743130000.00.71398912015-08-111.052027e+06496342796500.00.70808722015-08-127.923370e+05203664018400.01.06000032015-08-132.181182e+06284273935400.01.22000042015-08-144.154763e+063174109594000.01.810000generatedCoinsexchangeVolume(USD)027817.34375405283.0128027.812501463100.0227370.937502150620.0328268.125004068680.0431106.718754637030.0

让我们确认日期列是否需要转换:
# Confirm the date column is a stringprint(eth.info())

< class 'pandas.core.frame.DataFrame'> RangeIndex: 1014 entries, 0 to 1013Data columns (total 7 columns):date1014 non-null objecttxVolume(USD)1014 non-null float64txCount1014 non-null int64marketcap(USD)1014 non-null float64price(USD)1014 non-null float64generatedCoins1014 non-null float64exchangeVolume(USD)1014 non-null float64dtypes: float64(5), int64(1), object(1)memory usage: 55.5+ KBNone

date列确实是一个字符串, 记住-在Python中被表示为对象类型。你可以使用pandas中的.to_datetime()方法将其转换为datetime类型。下面的控制台包含转换列的调用。你能否通过根据数据集中的日期表示方式指定指令来完成它?
你是否使用’ %Y-%m-%d’ 完成了?大!
日期时间对象的组成部分
现在你将datetime对象作为日期列, 你可以提取日期的特定组成部分, 例如月, 日或年, 所有这些都可以用作对象的属性:
# Print datetime attributesprint(eth['date'][0].month)print(eth['date'][0].day)print(eth['date'][0].year)

8102015

日期属性通常用于按特定时间范围对数据进行分组。例如, 你可以查看每年生成多少醚:
from collections import defaultdictimport matplotlib.pyplot as plt# Initialize defaultdict of type floatyearly_total_coins = defaultdict(float)# Loop over the rows of ethfor day in eth.iterrows():# Get the datedates = day[1][0]# Get the number of coins generatednum_coins = day[1][5]# Add the total number of coins to the current value for the yearyearly_total_coins[dates.year] += num_coins# Print yearly_total_coinsprint(yearly_total_coins)# Visualize aggregated dataplt.bar(range(len(yearly_total_coins)), list(yearly_total_coins.values()), align='center')plt.xticks(range(len(yearly_total_coins)), list(yearly_total_coins.keys()))plt.title('# of ethers generated by year')plt.show()

defaultdict(< class 'float'> , {2015: 3805167.8125, 2016: 11321892.96875, 2017: 9230132.65625, 2018: 2849975.625})

将字符串转换为日期作为datetime对象

文章图片
加减时间
使用日期时, 另一种常见情况是从某个日期获得过去30、60或90天的日期。在Python中, datetime模块中的timedelta对象用于表示datetime对象中的差异。你可以通过传递任意数量的关键字参数(例如天, 秒, 微秒, 毫秒, 分钟, 小时和周)来创建时间增量。
一旦有了一个timedelta对象, 就可以从datetime对象中添加或减去它, 以获得另一个datetime对象。在下面的控制台中尝试:
用DatetimeIndex索引熊猫数据框
将date列转换为datetime格式后, 通常最好按日期对DataFrame进行索引, 从而创建DatetimeIndex。与datetime类型类似, DatetimeIndex是一种特殊的索引类型, 旨在与日期和时间一起使用。通过使用inset参数设置为True的.set_index()方法, 可以从数据集中删除日期列, 并将其附加为DataFrame的索引:
# Set indexeth.set_index('date', inplace=True)print(eth.head(5))

txVolumetxCountmarketCappricegeneratedCoins\date2015-08-101.193012e+06203743130000.00.71398927817.343752015-08-111.052027e+06496342796500.00.70808728027.812502015-08-127.923370e+05203664018400.01.06000027370.937502015-08-132.181182e+06284273935400.01.22000028268.125002015-08-144.154763e+063174109594000.01.81000031106.71875exchangeVolumedate2015-08-10405283.02015-08-111463100.02015-08-122150620.02015-08-134068680.02015-08-144637030.0

在DataFrame中设置DatetimeIndex可以解锁一整套有用的功能。例如, 当可视化时间序列数据时, 熊猫会自动为x轴创建合理间隔的日期标签:
eth.txCount.plot(title='# of transactions')plt.show()

将字符串转换为日期作为datetime对象

文章图片
很整洁吧?
部分字符串索引和切片
也许最有用的功能是部分字符串索引和切片, 这使你可以轻松地子集数据。假设你想仔细观察上图所示的2018年1月左右的峰值。以下代码使用部分字符串索引和切片来观察2017年12月至2018年2月之间的交易数量。
# Subset data around peakpeak_eth = eth['2017-12': '2018-2']peak_eth.txCount.plot(title='# of transactions around peak')

将字符串转换为日期作为datetime对象

文章图片
好吧, 那很容易!你是否注意到部分字符串索引包含边界, 这与典型的Python索引不同?
概括
从股票价格到航班时刻, 包含日期和时间的数据在各种各样的领域中都是不成熟的。能够有效处理此类数据对于回答从何时, 多长时间或多频率开始的问题至关重要。
在本教程中, 你:
  • 了解有关Python的指令以处理日期的各种表示方式。
  • 了解了如何使用datetime模块中的.strptime()方法将字符串转换为日期。
  • 了解了如何使用pandas中的.to_datetime()方法转换DataFrames中的日期字符串列。
  • 了解了datetime对象的组件以及如何将其作为对象的属性进行访问。
  • 了解了如何使用timedelta对象进行日期算术。
  • 学习了使用DatetimeIndex为DataFrames编制索引, 并探讨了其有用性的一些示例。
Python中的datetime和DatetimeIndex对象提供了一种更易于管理和直观的方式来处理日期和时间。如果你对学习更高级的技术感到好奇, 并且渴望获得一些动手实践来操纵, 分析和可视化时间序列数据, 请查看Python中的操纵时间序列数据, Python中的时间序列分析简介和时间可视化有关srcmini的Python课程中的系列数据。
学习愉快!

    推荐阅读