使 Pandas 与 Pendulum 一起工作
Making Pandas work with Pendulum
我最近偶然发现了一个新的很棒的 pendulum
library 可以更轻松地处理日期时间。
在 pandas
中,有这个方便的 to_datetime()
method 允许将系列和其他对象转换为日期时间:
raw_data['Mycol'] = pd.to_datetime(raw_data['Mycol'], format='%d%b%Y:%H:%M:%S.%f')
创建自定义 to_<something>
方法的规范方法是什么 -
在这种情况下,to_pendulum()
方法能够将一系列日期字符串直接转换为 Pendulum
objects?
这可能会导致 Series
具有各种有趣的功能,例如,将一系列日期字符串转换为一系列 "offsets from now" - human datetime diffs。
What would be the canonical way to create a custom to_<something>
method - in this case to_pendulum()
method which would be able to
convert Series of date strings directly to Pendulum
objects?
稍微浏览了 API 之后,我必须说我对他们所做的事情印象深刻。不幸的是,我认为 Pendulum
和 pandas
不能一起工作(至少,对于当前的最新版本 - v0.21
)。
最重要的原因是 pandas
本身不支持 Pendulum
作为数据类型。所有本机支持的数据类型(np.int
、np.float
和 np.datetime64
)都以某种形式支持矢量化。使用数据框,比起普通循环和列表,你不会获得一丝一毫的性能改进。如果有的话,在带有 Pendulum
对象的 Series
上调用 apply
将会 变慢 (因为所有 API 开销) .
另一个原因是 Pendulum
是 datetime
的子类 -
from datetime import datetime
isinstance(pendulum.now(), datetime)
True
这很重要,因为如上所述,datetime
是受支持的数据类型,因此 pandas 将 尝试 强制 datetime
到 pandas' 本机日期时间格式 - Timestamp
。这是一个例子。
print(s)
0 2017-11-09 18:43:45
1 2017-11-09 20:15:27
2 2017-11-09 22:29:00
3 2017-11-09 23:42:34
4 2017-11-10 00:09:40
5 2017-11-10 00:23:14
6 2017-11-10 03:32:17
7 2017-11-10 10:59:24
8 2017-11-10 11:12:59
9 2017-11-10 13:49:09
s = s.apply(pendulum.parse)
s
0 2017-11-09 18:43:45+00:00
1 2017-11-09 20:15:27+00:00
2 2017-11-09 22:29:00+00:00
3 2017-11-09 23:42:34+00:00
4 2017-11-10 00:09:40+00:00
5 2017-11-10 00:23:14+00:00
6 2017-11-10 03:32:17+00:00
7 2017-11-10 10:59:24+00:00
8 2017-11-10 11:12:59+00:00
9 2017-11-10 13:49:09+00:00
Name: timestamp, dtype: datetime64[ns, <TimezoneInfo [UTC, GMT, +00:00:00, STD]>]
s[0]
Timestamp('2017-11-09 18:43:45+0000', tz='<TimezoneInfo [UTC, GMT, +00:00:00, STD]>')
type(s[0])
pandas._libs.tslib.Timestamp
因此,需要一些困难(涉及 dtype=object
),您可以将 Pendulum
个对象加载到数据帧中。这是你如何做到的 -
v = np.vectorize(pendulum.parse)
s = pd.Series(v(s), dtype=object)
s
0 2017-11-09T18:43:45+00:00
1 2017-11-09T20:15:27+00:00
2 2017-11-09T22:29:00+00:00
3 2017-11-09T23:42:34+00:00
4 2017-11-10T00:09:40+00:00
5 2017-11-10T00:23:14+00:00
6 2017-11-10T03:32:17+00:00
7 2017-11-10T10:59:24+00:00
8 2017-11-10T11:12:59+00:00
9 2017-11-10T13:49:09+00:00
s[0]
<Pendulum [2017-11-09T18:43:45+00:00]>
然而,这基本上是无用的,因为调用 any pendulum
方法(通过 apply
)现在不仅非常慢,而且结果再次被强制 Timestamp
,这是徒劳的。
我最近偶然发现了一个新的很棒的 pendulum
library 可以更轻松地处理日期时间。
在 pandas
中,有这个方便的 to_datetime()
method 允许将系列和其他对象转换为日期时间:
raw_data['Mycol'] = pd.to_datetime(raw_data['Mycol'], format='%d%b%Y:%H:%M:%S.%f')
创建自定义 to_<something>
方法的规范方法是什么 -
在这种情况下,to_pendulum()
方法能够将一系列日期字符串直接转换为 Pendulum
objects?
这可能会导致 Series
具有各种有趣的功能,例如,将一系列日期字符串转换为一系列 "offsets from now" - human datetime diffs。
What would be the canonical way to create a custom
to_<something>
method - in this caseto_pendulum()
method which would be able to convert Series of date strings directly toPendulum
objects?
稍微浏览了 API 之后,我必须说我对他们所做的事情印象深刻。不幸的是,我认为 Pendulum
和 pandas
不能一起工作(至少,对于当前的最新版本 - v0.21
)。
最重要的原因是 pandas
本身不支持 Pendulum
作为数据类型。所有本机支持的数据类型(np.int
、np.float
和 np.datetime64
)都以某种形式支持矢量化。使用数据框,比起普通循环和列表,你不会获得一丝一毫的性能改进。如果有的话,在带有 Pendulum
对象的 Series
上调用 apply
将会 变慢 (因为所有 API 开销) .
另一个原因是 Pendulum
是 datetime
的子类 -
from datetime import datetime
isinstance(pendulum.now(), datetime)
True
这很重要,因为如上所述,datetime
是受支持的数据类型,因此 pandas 将 尝试 强制 datetime
到 pandas' 本机日期时间格式 - Timestamp
。这是一个例子。
print(s)
0 2017-11-09 18:43:45
1 2017-11-09 20:15:27
2 2017-11-09 22:29:00
3 2017-11-09 23:42:34
4 2017-11-10 00:09:40
5 2017-11-10 00:23:14
6 2017-11-10 03:32:17
7 2017-11-10 10:59:24
8 2017-11-10 11:12:59
9 2017-11-10 13:49:09
s = s.apply(pendulum.parse)
s
0 2017-11-09 18:43:45+00:00
1 2017-11-09 20:15:27+00:00
2 2017-11-09 22:29:00+00:00
3 2017-11-09 23:42:34+00:00
4 2017-11-10 00:09:40+00:00
5 2017-11-10 00:23:14+00:00
6 2017-11-10 03:32:17+00:00
7 2017-11-10 10:59:24+00:00
8 2017-11-10 11:12:59+00:00
9 2017-11-10 13:49:09+00:00
Name: timestamp, dtype: datetime64[ns, <TimezoneInfo [UTC, GMT, +00:00:00, STD]>]
s[0]
Timestamp('2017-11-09 18:43:45+0000', tz='<TimezoneInfo [UTC, GMT, +00:00:00, STD]>')
type(s[0])
pandas._libs.tslib.Timestamp
因此,需要一些困难(涉及 dtype=object
),您可以将 Pendulum
个对象加载到数据帧中。这是你如何做到的 -
v = np.vectorize(pendulum.parse)
s = pd.Series(v(s), dtype=object)
s
0 2017-11-09T18:43:45+00:00
1 2017-11-09T20:15:27+00:00
2 2017-11-09T22:29:00+00:00
3 2017-11-09T23:42:34+00:00
4 2017-11-10T00:09:40+00:00
5 2017-11-10T00:23:14+00:00
6 2017-11-10T03:32:17+00:00
7 2017-11-10T10:59:24+00:00
8 2017-11-10T11:12:59+00:00
9 2017-11-10T13:49:09+00:00
s[0]
<Pendulum [2017-11-09T18:43:45+00:00]>
然而,这基本上是无用的,因为调用 any pendulum
方法(通过 apply
)现在不仅非常慢,而且结果再次被强制 Timestamp
,这是徒劳的。