日期时间转换 - 如何提取推断格式?

cs9*_*s95 28 python datetime pandas

这是一组日期时间值:

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)
Run Code Online (Sandbox Code Playgroud)

pd.to_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)
Run Code Online (Sandbox Code Playgroud)

如何动态确定pd.to_datetime推断出的日期时间格式?有点像:( %Y-%m-%dT...抱歉,我的约会时间非常糟糕).

Ale*_*ley 29

我不认为在熊猫中完全普遍地做这件事是可能的.

正如其他评论和答案中所提到的,内部函数_guess_datetime_format接近于您所要求的内容,但它对可编辑格式的构成有严格的标准,因此它只适用于受限制的日期时间字符串类.

这些标准_guess_datetime_format这些行的函数中列出,您还可以在test_parsing脚本中看到一些好的和坏的格式示例.

一些要点是:

  • 年,月,日必须各自存在且可识别
  • 这一年必须有四位数
  • 如果使用微秒,则必​​须使用正好六位数
  • 你不能指定时区

这意味着尽管它们是有效的ISO 8601格式,它仍然无法猜测问题中datetime字符串的格式:

>>> 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
Run Code Online (Sandbox Code Playgroud)

在这种情况下,删除时区并将微秒填充到六位数就足以使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'
Run Code Online (Sandbox Code Playgroud)

这可能和它一样好.

如果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
Run Code Online (Sandbox Code Playgroud)

您提供的数组中的日期将被识别为以下格式:

>>> is_iso8601('2016-05-01T00:00:59.3+10:00')
True
Run Code Online (Sandbox Code Playgroud)

但是这并没有提供问题所要求的内容,我也没有看到任何可行的方法来恢复parse_iso_8601_datetime函数识别的确切格式.

如果将字符串解析为ISO 8601格式失败,则pandas将回退到使用parse()第三方dateutil库中的函数(调用方式parse_datetime_string).这样可以提供出色的解析灵活性,但同样,我不知道从这个函数中提取已识别的日期时间格式的任何好方法.

如果这两个这两个解析器的失败,无论是熊猫引发错误,忽略字符串或默认NaT(这取决于用户指定).不再进一步尝试解析字符串或猜测字符串的格式.


den*_*ufa 8

DateInfer(PyDateInfer)库允许根据可用日期的顺序推断日期:

github.com/wdm0006/dateinfer

来自docs的用法:

>>> 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'
>>>
Run Code Online (Sandbox Code Playgroud)

免责声明:我已经使用过,然后为这个库做出了贡献


Flo*_*oor 5

您可以使用_guess_datetime_formatfrom core.tools来获取格式.即

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

输出:

'%Y-%m-%d'
Run Code Online (Sandbox Code Playgroud)

要了解有关此方法的更多信息,请参阅此处.希望能帮助到你.