Ответ 1
Я не думаю, что это можно сделать в полной общности в pandas.
Как упоминалось в других комментариях и ответах, внутренняя функция _guess_datetime_format
близка к тому, что вы просите, но имеет строгие критерии для того, что составляет допустимый формат, и поэтому он будет работать только для ограниченного класса строк datetime.
Эти критерии указаны в _guess_datetime_format
на этих строках, и вы также можете увидеть некоторые примеры хороших и плохих форматов в test_parsing script.
Некоторые из основных моментов:
- каждый год, месяц и день должны присутствовать и идентифицироваться
- год должен иметь четыре цифры
- ровно шесть цифр должны использоваться при использовании микросекунд
- вы не можете указать часовой пояс
Это означает, что он не сможет угадать формат строк datetime в вопросе, несмотря на то, что он является допустимым ISO 8601:
>>> 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
В этом случае сбросить часовой пояс и отложить микросекунды до шести цифр достаточно, чтобы pandas распознал формат:
>>> 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'
Это, вероятно, так же хорошо, как и получается.
Если pd.to_datetime
не предлагается вывести формат массива или задать строку формата, чтобы попробовать, он просто попытается разобрать каждую строку отдельно и надеяться, что она будет успешной. Крайне важно, чтобы для этого не нужно было делать предварительный формат.
Сначала pandas анализирует строку, предполагая, что она (приблизительно) в формате ISO 8601. Это начинается при вызове _string_to_dts
и в конечном итоге попадает на низкоуровневый parse_iso_8601_datetime
, которая выполняет тяжелую работу.
Вы можете проверить, может ли ваша строка обрабатываться таким образом, используя функцию _test_parse_iso8601
. Например:
from pandas._libs.tslib import _test_parse_iso8601
def is_iso8601(string):
try:
_test_parse_iso8601(string)
return True
except ValueError:
return False
Даты в массиве, который вы даете, распознаются в этом формате:
>>> is_iso8601('2016-05-01T00:00:59.3+10:00')
True
Но это не дает то, о чем спрашивает вопрос, и я не вижу реалистичного способа восстановления точного формата, который распознается функцией parse_iso_8601_datetime
.
Если разбор строки в формате ISO 8601 завершается неудачно, pandas возвращается к использованию функции parse()
от стороннего dateutil library (называется parse_datetime_string
). Это дает фантастический уровень гибкости синтаксического анализа, но, опять же, я не знаю, какой хороший способ извлечь признанный формат даты и времени из этой функции.
Если оба из этих парсеров терпят неудачу, pandas вызывает ошибку, игнорирует строку или значения по умолчанию NaT
(в зависимости от того, что указывает пользователь). Не предпринимается дальнейшая попытка разобрать строку или угадать формат строки.