python - pd to_datetime 不将 DDMMMYYYY 日期转换为 python 中的日期时间

标签 python pandas datetime

这是我的数据的样子。如您所见,有些列的格式为 DDMMMYYYY,有些是 NaN,有些是标准的 DD/MM/YYYY 格式。

completion_date_latest      15/03/2001
completion_date_original    15/03/2001
customer_birth_date_1       30/11/1970
customer_birth_date_2       20/11/1971
d_start                      01Feb2018
latest_maturity_date        28/02/2021
latest_valuation_date       15/03/2001
sdate                              NaN
startdt_def                        NaN
obs_date                     01Feb2018

我想将它们转换为日期时间字段。我在名为 varlist2 的列表中有一个列列表,我循环遍历它们以 a) 删除 NA 和 b) 使用 to_datetime 函数转换为日期时间:

for m in range (0,len(varlist2)):
    date_var = varlist2[m]
    print('MM_Dates transform variable: ' + date_var)

    mm_dates_base[date_var] = pd.to_datetime(mm_dates_base[date_var], errors='ignore', dayfirst=True)
    mm_dates_base[date_var] = mm_dates_base[date_var].fillna('')

但是,当我检查我的输出时,我得到了这个,其中 d_start 和 obs_date 没有被转换。知道为什么会出现这种情况以及我可以做些什么来解决这个问题吗?

In [111]: print(mm_dates_base.iloc[0])
completion_date_latest      2001-03-15 00:00:00
completion_date_original    2001-03-15 00:00:00
customer_birth_date_1       1970-11-30 00:00:00
customer_birth_date_2       1971-11-20 00:00:00
d_start                               01Feb2018
latest_maturity_date        2021-02-28 00:00:00
latest_valuation_date       2001-03-15 00:00:00
sdate                                          
startdt_def                                    
obs_date                              01Feb2018

关于如何同时处理 DDMMMYYYY 日期的任何想法?

最佳答案

您可以选择由 varlist2 列定义的所有列到 DataFrame,然后使用 apply + to_datetime如果无法转换,使用 errors='coerce' 将有问题的格式转换为 NaT。最后将 NaTs 替换为 combine_first并分配回去:

df1 = mm_dates_base[varlist2].apply(pd.to_datetime, errors='coerce', dayfirst=True)
df2 = mm_dates_base[varlist2].apply(pd.to_datetime, errors='coerce', format='%d%b%Y')

mm_dates_base[varlist2] = df1.combine_first(df2)
print (mm_dates_base)
  completion_date_latest completion_date_original customer_birth_date_1  \
0             2001-03-15               2001-03-15            1970-11-30   

  customer_birth_date_2    d_start latest_maturity_date latest_valuation_date  \
0            1971-11-20 2018-02-01           2021-02-28            2001-03-15   

  sdate startdt_def   obs_date  
0   NaT         NaT 2018-02-01  

另一个更快的解决方案是循环每一列:

for col in varlist2:
    a = pd.to_datetime(mm_dates_base[col], errors='coerce', dayfirst=True)
    b = pd.to_datetime(mm_dates_base[col], errors='coerce', format='%d%b%Y')
    mm_dates_base[col] = a.combine_first(b)

快速比较:

#[100 rows x 10 columns]
mm_dates_base = pd.concat([df] * 100, ignore_index=True)
In [41]: %%timeit
    ...: 
    ...: for col in varlist2:
    ...:     a = pd.to_datetime(mm_dates_base[col], errors='coerce', dayfirst=True)
    ...:     b = pd.to_datetime(mm_dates_base[col], errors='coerce', format='%d%b%Y')
    ...:     mm_dates_base[col] = a.combine_first(b)
    ...:     
5.13 ms ± 46.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


In [43]: %%timeit
    ...: df1 = mm_dates_base[varlist2].apply(pd.to_datetime, errors='coerce', dayfirst=True)
    ...: df2 = mm_dates_base[varlist2].apply(pd.to_datetime, errors='coerce', format='%d%b%Y')
    ...: 
    ...: mm_dates_base[varlist2] = df1.combine_first(df2)
    ...: 
14.1 ms ± 92.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

关于python - pd to_datetime 不将 DDMMMYYYY 日期转换为 python 中的日期时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49779861/

相关文章:

python - 使用公共(public)键将带有公共(public)键作为元素的字典的 Pandas Dataframe 列转换为单独的数据框

php - 如何让周从星期日开始?

python - Django 表单搜索

python - 将数据发布到 django 管理表单

python 或 dask 并行生成器?

java - 从日历中获取日期之前的 18 年

php - SQL-仅当列与当前时间相等时才选择行

python - 覆盖 "from <my_object> import <name>"功能?

python - 如何在 Python 中管理多个进程?

python - 用于大数据的 Python 替代方案