28 votes

Conversion Datetime - Comment extraire le format déduit?

Voici un tableau de valeurs datetime:

 array = np.array(['2016-05-01T00:00:59.3+10:00', '2016-05-01T00:02:59.4+10:00',
                  '2016-05-01T00:03:59.4+10:00', '2016-05-01T00:13:00.1+10:00',
                  '2016-05-01T00:22:00.5+10:00', '2016-05-01T00:31:01.1+10:00'],
        dtype=object)
 

pd.to_datetime est très bon pour déduire des formats datetime.

 array = pd.to_datetime(array)

print(array)
DatetimeIndex(['2016-04-30 14:00:59.300000', '2016-04-30 14:02:59.400000',
               '2016-04-30 14:03:59.400000', '2016-04-30 14:13:00.100000',
               '2016-04-30 14:22:00.500000', '2016-04-30 14:31:01.100000'],
              dtype='datetime64[ns]', freq=None)
 

Comment puis-je déterminer dynamiquement quel format datetime pd.to_datetime déduit? Quelque chose comme: %Y-%m-%dT... (désolé, mon foo datetime est vraiment mauvais ).

29voto

ajcr Points 4047

Je ne pense pas que c'est possible de le faire dans tous les cas dans les pandas.

Comme mentionné dans d'autres commentaires et réponses, la fonction interne _guess_datetime_format est proche de ce que vous demandez, mais il a des critères stricts pour ce qui constitue une deviner le format et donc il ne fonctionne que pour une classe restreinte de datetime cordes.

Ces critères sont énoncés dans l' _guess_datetime_format fonction de ces lignes et vous pouvez également voir quelques exemples de bons et de mauvais dans le format de test_parsing script.

Certains des principaux points sont les suivants:

  • année, mois et jour doivent être présents et identifiables
  • l'année doit comporter quatre chiffres
  • exactement six chiffres doivent être utilisés si l'aide de microsecondes
  • vous ne pouvez pas spécifier un fuseau horaire

Cela signifie qu'il ne pourra pas deviner le format datetime chaînes dans la question, bien qu'ils soient valides ISO 8601 format:

>>> from pandas.core.tools.datetimes import _guess_datetime_format_for_array
>>> array = np.array(['2016-05-01T00:00:59.3+10:00'])
>>> _guess_datetime_format_for_array(array)
# returns None

Dans ce cas, la suppression du fuseau horaire et de rembourrage de quelques microsecondes à six chiffres est assez pour faire les pandas de reconnaître le format:

>>> array = np.array(['2016-05-01T00:00:59.300000']) # six digits, no tz
>>> _guess_datetime_format_for_array(array)
'%Y-%m-%dT%H:%M:%S.%f'

C'est probablement aussi bon qu'il obtient.

Si pd.to_datetime est demandé de ne pas déduire le format du tableau, ou d'une chaîne de format pour essayer, il suffit de l'essayer et d'analyser chaque corde séparément et espère que c'est réussi. Surtout, il n'a pas besoin d'en déduire un format à l'avance pour ce faire.

Tout d'abord, les pandas analyse la chaîne de caractères en supposant que c'est (environ) un format ISO 8601. Cela commence dans un appel à l' _string_to_dts et, finalement, frappe le faible niveau de l' parse_iso_8601_datetime fonction qui fait le travail dur.

Vous pouvez vérifier si votre chaîne est analysé à l'aide de cette manière l' _test_parse_iso8601 fonction. Par exemple:

from pandas._libs.tslib import _test_parse_iso8601

def is_iso8601(string):
    try:
        _test_parse_iso8601(string)
        return True
    except ValueError:
        return False

Les dates dans le tableau que vous donnez sont reconnus comme ce format:

>>> is_iso8601('2016-05-01T00:00:59.3+10:00')
True

Mais cela ne veut pas livrer ce que la question demande et je ne vois pas de façon réaliste pour récupérer le format exact qui est reconnu par l' parse_iso_8601_datetime fonction.

Si l'analyse de la chaîne de format ISO 8601 échoue, les pandas tombe en arrière à l'aide de l' parse() fonction à partir de la troisième partie dateutil bibliothèque (appelé par parse_datetime_string). Cela permet un niveau fantastique de l'analyse de la flexibilité, mais, encore une fois, je ne sais pas du tout bon moyen pour extraire le reconnu format datetime à partir de cette fonction.

Si à la fois de ces deux analyseurs échec, les pandas soit soulève une erreur, ignore la chaîne ou par défaut NaT (selon ce que l'utilisateur spécifie). Aucune tentative n'est faite pour analyser la chaîne, ou de deviner le format de la chaîne.

8voto

denfromufa Points 174

La bibliothèque DateInfer (PyDateInfer) permet de déduire des dates en fonction de la séquence des dates disponibles:

github.com/wdm0006/dateinfer

Utilisation à partir de documents:

 >>> import dateinfer
>>> dateinfer.infer(['Mon Jan 13 09:52:52 MST 2014', 'Tue Jan 21 15:30:00 EST 2014'])
'%a %b %d %H:%M:%S %Z %Y'
>>>
 

Avis de non-responsabilité: j'ai utilisé puis contribué à cette bibliothèque

5voto

Dark Points 20515

Vous pouvez utiliser _guess_datetime_format de core.tools pour obtenir le format. c'est à dire

 from pandas.core.tools import datetimes as tools
tools._guess_datetime_format(pd.to_datetime(array).format()[0][:10])
 

Production :

 '%Y-%m-%d'
 

Pour en savoir plus sur cette méthode, vous pouvez voir ici . J'espère que cela aide.

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