假设我在str
列中有以下数据集,其日期(date_str
)和int
列中午夜(seconds_past_midnight
)之后的秒数。我想根据这两列的组合来解析日期时间。
import pandas as pd
import numpy as np
n = 1000000
df = pd.DataFrame({'seconds_past_midnight': np.random.randint(34200, 57601, size=n), 'date_str': ['2015-07-14']*n})
print(df)
date_str seconds_past_midnight
0 2015-07-14 48642
1 2015-07-14 39170
2 2015-07-14 43940
3 2015-07-14 46927
4 2015-07-14 55376
5 2015-07-14 35859
6 2015-07-14 38705
7 2015-07-14 35932
8 2015-07-14 36874
9 2015-07-14 39487
... ... ...
999990 2015-07-14 54837
999991 2015-07-14 47146
999992 2015-07-14 54188
999993 2015-07-14 54729
999994 2015-07-14 35574
999995 2015-07-14 35815
999996 2015-07-14 38727
999997 2015-07-14 38374
999998 2015-07-14 53055
999999 2015-07-14 43303
[1000000 rows x 2 columns]
print(df.dtypes)
date_str object
seconds_past_midnight int64
dtype: object
我能想到的最简单的方法是根据这些秒数构造pd.Timedelta
并将它们添加到日期对象中,但是当使用pd.Timedelta
时,这基本上是一个行循环for循环做转换,这是非常缓慢的。
%time df.apply(lambda row: pd.to_datetime(row.date_str) + pd.Timedelta(row.seconds_past_midnight, 's'), axis=1)
CPU times: user 2min 5s, sys: 311 ms, total: 2min 5s
Wall time: 2min 5s
所以我想知道是否有办法加速这个过程?也许是我不知道的日期时间对象上的一些矢量化函数?我认为稍微提高速度的一种方法是使用multiprocessing
模块,也许我可以期望在8核PC上快4-6倍。另外,因为我在apply
中调用python函数,在这种情况下,cython或jit没有帮助吗?
答案 0 :(得分:2)
padding
答案 1 :(得分:2)
pd.to_datetime
和pd.to_timedelta
都已经过矢量化。
In [13]: np.random.seed(1234)
In [14]: df = pd.DataFrame({'seconds_past_midnight': np.random.randint(34200, 57601, size=n), 'date_str': ['2015-07-14']*n})
In [15]: df.head()
Out[15]:
date_str seconds_past_midnight
0 2015-07-14 35518
1 2015-07-14 51248
2 2015-07-14 56721
3 2015-07-14 57417
4 2015-07-14 42671
In [16]: df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1000000 entries, 0 to 999999
Data columns (total 2 columns):
date_str 1000000 non-null object
seconds_past_midnight 1000000 non-null int64
dtypes: int64(1), object(1)
memory usage: 22.9+ MB
In [17]: (pd.to_datetime(df['date_str']) + pd.to_timedelta(df['seconds_past_midnight'],unit='s')).head()
Out[17]:
0 2015-07-14 09:51:58
1 2015-07-14 14:14:08
2 2015-07-14 15:45:21
3 2015-07-14 15:56:57
4 2015-07-14 11:51:11
dtype: datetime64[ns]
In [18]: %timeit pd.to_datetime(df['date_str']) + pd.to_timedelta(df['seconds_past_midnight'],unit='s')
10 loops, best of 3: 187 ms per loop
这是当前的主人,它有几个性能改进。在0.16.2中,这慢了2倍。
答案 2 :(得分:1)
您还可以使用NumPy datetime64's and timedelta64's进行添加:
(np.array(df['date_str'], '<M8[D]') +
np.array(df['seconds_past_midnight'], dtype='<m8[s]'))
例如,
import pandas as pd
import numpy as np
np.random.seed(1234)
n = 1000000
df = pd.DataFrame({
'seconds_past_midnight': np.random.randint(34200, 57601, size=n),
'date_str': ['2015-07-14']*n})
包含对DataFrame的分配:
In [4]: pd.__version__
Out[6]: u'0.16.2+175.g5a9a9da'
In [7]: %timeit df['date'] = np.array(df['date_str'], '<M8[D]')+np.array(df['seconds_past_midnight'], dtype='<m8[s]')
10 loops, best of 3: 94.6 ms per loop
In [8]: %timeit df['date2'] = pd.to_datetime(df['date_str']) + pd.to_timedelta(df['seconds_past_midnight'],unit='s')
10 loops, best of 3: 188 ms per loop
In [12]: df['date'].equals(df['date2'])
Out[12]: True
(如果没有赋值给DataFrame,datetime64 / timedelta64 sum会返回一个NumPy数组,而to_datetime/to_timedelta
之和会返回一个Pandas系列,因此比较这些将是一个苹果与橙子的比较。)
答案 3 :(得分:0)
你可以解析strptime(“%Y-%m-%d%f”),%f在技术上是微秒,不知道这有用吗?