2 votes

Convertir une colonne pandas en datetime avec une valeur max inhabituelle

J'ai un DataFrame lu à partir d'une base de données. Il contient des dates qui m'indiquent la validité d'une ligne, malheureusement dans un format décimal (14 chiffres) comme ceci 20190130110429 ) ; de même, si l'entrée est encore valide (c'est-à-dire que la date est dans le futur), la colonne tient 999999999999999 (15 neuf).

Lorsque j'essaye de le convertir en datetime avec

pd.to_datetime(df['date'],format='%Y%m%d%H%M%S')

il échoue pour les 999... entrées. J'ai essayé de considérer les deux cas séparément

df['date'] = df['date'].astype(str)
mask = df['date']=='999999999999999'
df.loc[~mask,'date'] = pd.to_datetime(df.loc[~mask,'date'],format='%Y%m%d%H%M%S')
df.loc[mask,'date'] = pd.datetime.max # also tried np.datetime64(pd.datetime.max,unit='s')

Mais cela mélange les types :

[(x,type(x)) for x in df['date']

[(datetime.datetime(9999, 12, 31, 23, 59, 59, 999999), datetime.datetime),
 (1548846269000000000, int),
...
]

Avez-vous une idée de la manière de gérer cette situation ?

PS : Juste avant d'envoyer la question, je viens de la résoudre en

    df['date'] = df['date'].astype(str)
    df['date'] = df['date'].str.replace('999999999999999',pd.Timestamp.max.strftime('%Y%m%d%H%M%S'))
    df['date'] = pd.to_datetime(df['date'],format='%Y%m%d%H%M%S')

Cela me donne '2262-04-11 23:47:16.854775807' comme date maximale. (Comment) Est-il possible de stocker la datetime64[s] ou [us] maximum au lieu de la datetime64[ns] ?

1voto

coldspeed Points 111053

pd.to_datetime renvoie un Timestamp :

pd.to_datetime('20190130110429')
# Timestamp('2019-01-30 11:04:29')

Il s'agit du format de date natif de pandas. PAR CONTRE, pd.datetime est d'un type différent ( datetime.datetime ). Ils sont différents et parfois non compatibles. Ce que vous avez est un bon exemple de cela. Plus précisément, vous remarquerez qu'ils ont des valeurs max différentes.

pd.datetime.max
# datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)
pd.Timestamp.max
# Timestamp('2262-04-11 23:47:16.854775807')

Comme la première n'est pas compatible avec la seconde, le résultat est une colonne d'objets (pandas ne peut pas la convertir en scalaire). Timestamp ) et le résultat est un mélange bizarre de dates et d'entiers.

Ma suggestion serait la suivante replace y fillna :

df['date'] = (
    pd.to_datetime(df['date'].replace('999999999999999', np.nan))
      .fillna(pd.Timestamp.max))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X