关于加速代码的想法

数据挖掘 Python 熊猫
2022-02-24 00:50:26
cols = ['permit_creation_date', 'current_status_date','filed_date', 'issued_date', 'completed_date', 
           'first_construction_document_date', 'permit_expiration_date']

df_raw[cols] = df_raw[cols].apply(pd.to_datetime)

我编写了这段代码来转换数据框中的一些列,以将数据类型转换为日期时间。当我在 jupyter notebook 中运行单元时,运行时大约需要 1 分钟。关于如何加快运行时的任何想法。

2个回答

直接通过panda系列来pandas.to_datetime()函数。它比使用 apply 函数并pandas.to_datetime作为参数传递更快。

In[20]: %timeit -n 1000 pd.to_datetime(mdp)
96.1 µs ± 12.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In[21]: %timeit -n 1000 mdp.apply(pd.to_datetime)
5.59 ms ± 91.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

在数据帧的情况下,循环遍历该系列也可以正常工作。

In[45]: %timeit [pd.to_datetime(df[x]) for x in df]
230 µs ± 20.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)`

In[46]: %timeit df.apply(pd.to_datetime)
1.22 ms ± 10.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

这是一个稍微快一点的版本(这个想法是,如果您有大量的日期要解析,那么存储您已经解析的日期并查找它们比每次都重新解析它们更有效):

def fast_dates_parse(df):
    dates = {date: pd.to_datetime(date) for date in set(df[cols].values.ravel('K'))}
    for i in df.columns:
        df[i] = df[i].apply(lambda x: dates[x])

让我们创建一个包含 10000 行和 2 列的示例 DataFrame 来评估以下性能:

import pandas as pd
import numpy as np

df_raw = pd.DataFrame()
for i in range(2):
    init = {'day': np.random.randint(1, 28, 10000),
            'month': np.random.randint(1, 12, 10000),
            'year': 2000+np.random.randint(1, 18, 10000)}
    df = pd.DataFrame(init)
    df_raw['date_'+str(i)] = df['day'].astype(str)+'/'+df['month'].astype(str)+'/'+df['year'].astype(str)

cols = ['date_0', 'date_1']

让我们尝试对基线方法进行计时:

%timeit df_raw[cols].apply(pd.to_datetime)

这给了我们:

4.67 s ± 270 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

接下来,让我们尝试我们的新方法(注意,.copy()使用该函数更改 DataFrame 时应删除):

%timeit fast_dates_parse(df_raw[cols].copy())

这给了我们:

1.58 s ± 88.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)