我有一个带有 ca 的 pandas 数据框。 250,000 行 x 6 列。其中一列是日期,格式为文本。我需要做三件事:
- 从文本转换为日期
- 创建一个日期,其中月份和年份与转换后的日期相同,但日期始终为 15 号
- 在上面计算的日期后一个月计算日期
我用 apply 语句完成所有这些。它们可以工作,但对我来说似乎很慢:总共 7 秒,而在同一台机器上,即使没有并行化,任何 SQL 也只需要几分之一秒。如果这是一次性的,我不会花时间来加快速度,但我必须在多个相似大小的数据帧上多次执行此操作。
有什么方法可以加快我的代码速度吗?非常感谢!
#this takes 3.1 seconds
df['date_reformatted'] = df['date_raw'].apply(lambda r: datetime.datetime.strptime(r, "%d/%m/%Y") )
# this takes 0.8 seconds
df['date_15']= df['date_reformatted'].apply(lambda r: datetime.date( r.year, r.month,15 ) )
# this takes 3.3 seconds
df['date_next_month']= df['date_15'].apply(lambda x: x + dateutil.relativedelta.relativedelta(months=1) )
请您参考如下方法:
尝试只使用整数和字符串。仅在确实需要时才转换为日期时间对象。
%%timeit -n10 df = pd.DataFrame({'date_raw': ['31/12/2000']*250000})
_, months, years = zip(*df.date_raw.str.split('/'))
months_years = [(1 if m == '12' else int(m) + 1,
int(y) + 1 if m == '12' else int(y))
for m, y in zip(months, years)]
# New dates in dd-mm-yyyy format:
df['new_date'] = ['15-{0}-{1}'.format(x[0], x[1]) for x in months_years]
10 loops, best of 3: 583 ms per loop
>>> df.tail()
date_raw new_date
249995 31/12/2000 15-1-2001
249996 31/12/2000 15-1-2001
249997 31/12/2000 15-1-2001
249998 31/12/2000 15-1-2001
249999 31/12/2000 15-1-2001
新日期以文本形式显示(这就是它速度很快的原因)。创建 datetime 对象有点耗时,但如果你真的需要它们:
%%timeit
df['new_date'].apply(lambda r: datetime.datetime.strptime(r, "%d-%m-%Y") )
1 loops, best of 3: 2.72 s per loop
