Python 有没有办法在午夜过后的几秒钟内加速日期分析器?

Python 有没有办法在午夜过后的几秒钟内加速日期分析器?,python,pandas,python-multiprocessing,Python,Pandas,Python Multiprocessing,假设我有以下数据集,其中日期(str)在date\u str列中,午夜后秒数(int)在seconds\u poster\u midnight列中。我想根据这两列的组合来解析datetime 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': ['201

假设我有以下数据集,其中日期(
str
)在
date\u str
列中,午夜后秒数(
int
)在
seconds\u poster\u midnight
列中。我想根据这两列的组合来解析datetime

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
,并将它们添加到date对象中,但在使用
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

因此,我想知道是否有办法加快这一进程?也许是datetime对象上的一些向量化函数,我不知道?我认为稍微提高速度的一种方法是使用
多处理模块,在8核PC上可能会快4-6倍。此外,由于我在
apply
中调用python函数,cython或jit在这种情况下没有帮助?

您可以解析它的strtime(%Y-%m-%d%f)),从技术上讲,%f是微秒,不知道这是否有帮助?

你可以用strtime(%Y-%m-%d%f)来解析它,%f从技术上讲是微秒,不知道这是否有帮助?

这两个
pd.to\u datetime
pd.to\u timedelta
都已经矢量化了

dates = pd.to_datetime(df.date_str) + pd.to_timedelta(df.seconds_past_midnight, unit='s')
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
[13]中的
:np.random.seed(1234)
在[14]中:df=pd.DataFrame({'seconds\u pass\u midnight':np.random.randint(3420057601,size=n),'date\u str':['2015-07-14']*n})
In[15]:df.head()
出[15]:
日期(秒)午夜(秒)
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
在[16]:df.info()中
Int64Index:1000000个条目,0到999999
数据列(共2列):
日期\u str 1000000非空对象
超过午夜的秒数1000000非空int64
数据类型:int64(1),对象(1)
内存使用率:22.9+MB
在[17]中:(pd.to_datetime(df['date\u str'])和pd.to_timedelta(df['seconds\u pass'u midnight'],unit='s')).head()
出[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
数据类型:datetime64[ns]
在[18]中:%timeit pd.to_datetime(df['date\u str'])+pd.to_timedelta(df['seconds\u poster\u midnight'],单位为s'))
10个回路,最佳3个:每个回路187毫秒

这是与当前主机,其中有一些性能改进。在0.16.2中,速度慢了2倍。

到日期时间的pd和到时间增量的pd都已矢量化

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
[13]中的
:np.random.seed(1234)
在[14]中:df=pd.DataFrame({'seconds\u pass\u midnight':np.random.randint(3420057601,size=n),'date\u str':['2015-07-14']*n})
In[15]:df.head()
出[15]:
日期(秒)午夜(秒)
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
在[16]:df.info()中
Int64Index:1000000个条目,0到999999
数据列(共2列):
日期\u str 1000000非空对象
超过午夜的秒数1000000非空int64
数据类型:int64(1),对象(1)
内存使用率:22.9+MB
在[17]中:(pd.to_datetime(df['date\u str'])和pd.to_timedelta(df['seconds\u pass'u midnight'],unit='s')).head()
出[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
数据类型:datetime64[ns]
在[18]中:%timeit pd.to_datetime(df['date\u str'])+pd.to_timedelta(df['seconds\u poster\u midnight'],单位为s'))
10个回路,最佳3个:每个回路187毫秒

这是与当前主机,其中有一些性能改进。在0.16.2中,速度要慢2倍。

您还可以通过以下方式进行添加:

包括对数据帧的分配:

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
[4]中的
:pd.\u版本__
Out[6]:u'0.16.2+175.g5a9a9da'

在[7]:%timeit df['date']=np.array(df['date\u str'],'中,您还可以使用以下各项进行加法:

包括对数据帧的分配:

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
[4]中的
:pd.\u版本__
Out[6]:u'0.16.2+175.g5a9a9da'

在[7]:%timeit df['date']=np.array(df['date\u str'],'uh,我错过了
pd.to\u timedelta()
。非常感谢!:-)uh,我错过了
pd.to\u timedelta()
。非常感谢!:-)我忘记了
pd.to\u timedelta()
。非常感谢!:-)我忘了将
pd.to_timedelta()
。非常感谢!:-)