pd.to_datetime
может быть на порядок медленнее, если вы попытаетесь определить формат. В смешанных форматах вы можете попытаться проанализировать его несколько раз:
import pandas as pd
from functools import reduce
# dd-mm-yy dd-mm-YYYY YYYY-mm-dd
df = pd.DataFrame({'date': ['12-01-01', '12-01-2001', '2001-07-05',
'Jan 19', 'January 2019', '1 January 2019']})
Код:
formats = ['%d-%m-%y', '%d-%m-%Y', '%Y-%m-%d', '%b %y', '%B %Y', '%d %B %Y']
reduce(lambda l,r: l.combine_first(r),
[pd.to_datetime(df.date, format=fmt, errors='coerce') for fmt in formats])
0 2001-01-12
1 2001-01-12
2 2001-07-05
3 2019-01-01
4 2019-01-01
5 2019-01-01
Name: date, dtype: datetime64[ns]
В общем случае pd.to_datetime
может гибко анализировать большинство этих форматов, если указать dayfirst
. Хотя это все равно будет медленнее, чем попытка несколько раз проанализировать его с указанными форматами.
pd.to_datetime(df.date, errors='coerce', dayfirst=True)
#0 2001-01-12
#1 2001-01-12
#2 2001-07-05
#3 NaT
#4 2019-01-01
#5 2019-01-01
#Name: date, dtype: datetime64[ns]
df = pd.concat([df]*10000, ignore_index=True)
%timeit reduce(lambda l,r: l.combine_first(r), [pd.to_datetime(df.date, format=fmt, errors='coerce') for fmt in formats])
#287 ms ± 2.35 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit pd.to_datetime(df.date, errors='coerce', dayfirst=True)
#5.79 s ± 36.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Таким образом, вы все равно выигрываете, даже пытаясь разобрать его несколько раз, плюс вы не пропустите некоторые нестандартные форматы.