问题描述
我认为不可能在大熊猫中完全笼统地做到这一点。
正如其他评论和答案中所提到的那样,内部函数_guess_datetime_format
几乎是您所要的,但是对于构成可猜测格式的内容它具有严格的标准,因此它仅适用于日期时间字符串的受限类。
这些条件_guess_datetime_format
在这些行的函数中列出,并且您还可以在test_parsing脚本中看到一些格式好的示例。
一些要点是:
- 年,月和日必须分别存在且可识别
- 年份必须有四个数字
- 如果使用微秒,则必须使用准确的六位数
- 您无法指定时区
这意味着即使它们是有效的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
在这种情况下,放下时区并将微秒填充到六位数就足以使熊猫识别格式:
>>> 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库(由调用parse_datetime_string
)中的函数。这提供了极高的解析灵活性,但是,我不知道从此函数中提取公认的日期时间格式的任何好方法。
如果 这两个 这两个解析器的失败,熊猫要么引发错误,忽略字符串或默认NaT
(这取决于用户指定)。没有进一步尝试解析字符串或猜测字符串的格式。
解决方法
这是日期时间值的数组:
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
在推断日期时间格式方面非常擅长。
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)
如何动态找出pd.to_datetime
推断的日期时间格式?像这样:(%Y-%m-%dT...
对不起,我的datetime foo 真的很糟糕
)。