强制日期时间转换,强制日期时间dtype,在pandas

时间:2015-09-07 17:54:34

标签: python parsing datetime pandas converter

我的数据有几个日期的日期字段,但在数千万行中,某些行有错误。我只是在读取数据后立即将列转换为日期时间,以获得速度和内存限制,然而我似乎无法强制将NaT留给无效字符串而不是提高错误。我可以在字段中阅读uint32以便稍后强制转换为日期时间,但是一旦我们拥有parse_dates选项,这似乎就会变得非常缓慢。

样本数据位于帖子的底部。

这种方法可以很好地工作,因为数据总是格式良好:pd.read_table(filename,usecols=[0,8,9,11],parse_dates=[1,2])

但是,如果某些行无法转换,则会导致dtype对象,然后以后的操作会中断。

pd.read_table(filename,usecols=[0,8,9,11],parse_dates=[1,2],dtype={'LopNr': np.uint32,'INDATUMA': np.uint32,'UTDATUMA': np.uint32,'DIAGNOS': np.object}),假设在进入转换器之前dtype将应用于数据,会打扰某些行中的字符串:ValueError: invalid literal for long() with base 10: 'string'

pd.read_table(filename,usecols=[0,8,9,11],parse_dates=[1,2],dtype={'LopNr': np.uint32,'INDATUMA': 'datetime64','UTDATUMA': 'datetime64','DIAGNOS': np.object})无效,TypeError: the dtype <M8 is not supported for parsing, pass this column using parse_dates instead

如果我准备解除其字符串格式不可解析为日期的行,那么继续使用此类数据的有效方法是什么?

示例数据(所有有意义的数字都替换为。为保密),请注意两个日期在最后两行中格式不正确:

LopNr   AR  KON ALDER   LKF SJUKHUS MVO LT_KLIN INDATUMA    UTDATUMA    HDIA    DIAGNOS OP  PVARD   INSATT  UTSATT  VTID    EKOD.   EKOD.   ICD PEKARE  OPD.    OPD.    OPD.    OPD.    OPD.    OPD.    OPD.    OPD.    OPD.    OPD..   OPD..   OPD..
..  ....    .   .   ......  .....   ... ... 19970320    19970320    S...    S...        .   .   .   .   W....       ..              
..  ....    .   .   ......  .....   ... ... 19970306    19970307    S...    S...        .   .   .   .   W....       ..              
..  ....    .   ..  ......  .....   ... ... 19961219    19970208    Z...    Z... S...       .   .   .   ..  W....       ..          
..  ....    .   ..  ......  .....   ... ... 19970208    19970320    Z...    Z... S...       .   .   .   ..  W....       ..          
..  ....    .   ..  ......  .....   ... ... 19970604    19970611    I...    I... I... I...      .   .   .   .           ..          
..  ....    .   ..  ......  .....   ... ... 19970402    19970406    O800A   O800A       .   .   .   .           ..              
..  ....    .   ..  ......  .....   ... ... 19970412    19970415    R...    R... I... Z... J...     .   .   .   .           ..      
..  ....    .   ..  ......  .....   ... ... 19970520    19970523    R...    R... I... J...  V....   .   .   .   .           ..  .       
..  ....    .   ..  ......  .....   ... ... 19970504    19970507    I...    I...        .   .   .   .           ..              
..  ....    .   ..  ......  .....   ... ... 1997050     19970507    I...    I...        .   .   .   .           ..              
..  ....    .   ..  ......  .....   ... ... 19970504    string      I...    I...        .   .   .   .           ..              

1 个答案:

答案 0 :(得分:2)

你可以这样做:

parser = lambda x : pd.to_datetime(x, coerce=True)
pd.read_table(..., parse_dates=[0,1], date_parser=parser)

但这并不比只是读入然后解析更快。即使在默认情况下,也会在读入数据后进行解析。

df = pd.read_table(...)
df['INDATUMA'] = pd.to_datetime(df['INDATUMA'], coerce=True)
df['UTDATUMA'] = pd.to_datetime(df['UTDATUMA'], coerce=True)

如果你的日期格式相同,你可以通过传递格式看到非常显着的加速 - 有一个专门用于YYYYMMDD格式化日期的快速路径。

df = pd.read_table(...)
df['INDATUMA'] = pd.to_datetime(df['INDATUMA'], coerce=True, format='%Y%m%d')

另请注意,在下一版pandas(0.17)中,coerce参数将递减,您将改为errors='coerce'