将对象类型更改为datetime64[ns]-pandas

8
我正在分析Web服务器日志文件,其中日期时间格式如下。
02/Apr/2013:23:55:00 +0530

我将把这个转换成pandas日期时间格式。
df['Time'] = pd.to_datetime(df['Time'])

但它仍然是以对象格式存在的。
print df.dtypes

时间对象

为什么它没有改变为datetime64[ns]

Numpy版本

In [2]: np.__version__
Out[2]: '1.8.0'
3个回答

7

如果我有所遗漏,对不起...

df['Time'] = df['Time'].astype('datetime64')

我收到了两个错误:
  1. ValueError:带时区的datetime.datetime除非utc=True,否则无法转换为datetime64
  2. ValueError:数组必须全部是相同的时区
- PM0087

3

以下答案取决于您使用的Python版本。

Pandas的to_datetime无法识别您的自定义日期时间格式,您应该显式提供它:

>>> import pandas as pd
>>> from datetime import datetime
>>> df = pd.DataFrame({'Time':['02/Apr/2013:23:55:00 +0530']},index=['tst'])
>>> from functools import partial
>>> to_datetime_fmt = partial(pd.to_datetime, format='%d/%b/%Y:%H:%M:%S %z')

并应用此自定义转换器

>>> df['Time'] = df['Time'].apply(to_datetime_fmt)
>>> df.dtypes
Time    datetime64[ns]
dtype: object

请注意,此功能仅适用于python版本3.2及以上版本,在早期版本中不支持%z。您需要手动添加时间差。
>>> from datetime import timedelta
>>> df = pd.DataFrame({'Time':['02/Apr/2013:23:55:00 +0530']},index=['tst'])

将时间拆分为日期时间和偏移量

>>> def strptime_with_offset(string, format='%d/%b/%Y:%H:%M:%S'):
...    base_dt = datetime.strptime(string[:-6], format)
...    offset = int(string[-6:])
...    delta = timedelta(hours=offset/100, minutes=offset%100)
...    return base_dt + delta
...

并应用此转换函数:

>>> df['Time'] = df['Time'].apply(strptime_with_offset)
>>> df['Time']
tst   2013-04-03 05:25:00
Name: Time, dtype: datetime64[ns]
>>> df.dtypes
Time    datetime64[ns]
dtype: object

非常感谢您的回答。它出现了以下错误。为什么会添加一个空格?ValueError: time data '02/Apr/2013 23:55:00' does not match format '%d/%b/%Y:%H:%M:%S' - Nilani Algiriyage
首先,你的实际数据可能是 02/Apr/2013 23:55:00。你可以使用适当的格式,例如 '%d/%b/%Y %H:%M:%S'。其次,我的答案不太正确,我很快会更新它。 - alko
不,我的真实数据是以你发布的格式。例如,[02/Apr/2013:23:55:00 +0530],[02/Apr/2013:23:55:09 +0530],[02/Apr/2013:23:55:18 +0530]等。 - Nilani Algiriyage
当你加载数据时,可能会发生一些转换,请尝试检查dt['Time']的输出。我已经更新了我的答案,并提供了正确的转换函数,但没有足够的时间深入研究以找出错误所在(可能是pandas如何存储timedelta的问题)。 - alko

0

除了alko的方法,这段代码也可以正常工作。

from dateutil import parser

def parse(x):
    date, hh, mm, ss = x.split(':')
    dd, mo, yyyy = date.split('/')
    return parser.parse("%s %s %s %s:%s:%s" % (yyyy,mo,dd,hh,mm,ss))

df['Time'] = df['Time'].apply(lambda x:x[1:-7])

请注意,这里有意省略偏移量 +0530 并得到不同的结果,即 2013-04-02 23:55:00 而非 2013-04-03 05:25:00。我不知道哪个结果是“期望”的,但后者似乎更适合,因为您的数据可能具有不同的偏移量。 - alko
它必须是“-6”,而不是“-7”,否则您应该得到“ValueError()”。 - alko
@alko 谢谢,我明白了,:) - Nilani Algiriyage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接