将文本转换为numpy中的datetime64

3 投票
1 回答
5508 浏览
提问于 2025-04-18 18:20

我有一个包含字符串的numpy数组(顺便问一下,为什么字符串会被表示为对象呢?)

t = array(['21/02/2014 08:40:00 AM', '11/02/2014 10:50:00 PM',
           '07/04/2014 05:50:00 PM', '17/02/2014 10:20:00 PM',
           '07/03/2014 06:10:00 AM', '02/03/2014 12:25:00 PM',
           '05/02/2014 03:20:00 AM', '31/01/2014 12:30:00 AM',
           '28/02/2014 01:25:00 PM'], dtype=object)

我想把它转换成numpy.datetime64格式,精确到天。不过我找到的唯一解决办法是:

t = [datetime.strptime(tt,"%d/%m/%Y %H:%M:%S %p") for tt in t]
t = np.array(t,dtype='datetime64[us]').astype('datetime64[D]')

这难道还有更糟糕的办法吗?为什么我需要先转成原生的Python列表?肯定还有其他方法...

对了,我找不到在numpy或pandas中绘制日期直方图的方法。

1 个回答

1

日期格式是个问题,01/01/2015 这个格式不太明确。如果用 ISO 8601 格式的话,你可以直接用 numpy 来解析。但在你的情况下,因为你只想要日期,所以把数据拆分和重新排列会快很多:

t = np.array([datetime.strptime(d.split(None)[0], "%d/%m/%Y") 
for d in t],dtype='datetime64[us]').astype('datetime64[D]')

一些时间测试,首先是解析后再重新排列:

In [36]: %%timeit
from datetime import datetime
t = np.array(['21/02/2014 08:40:00', '11/02/2014 10:50:00 PM',
           '07/04/2014 05:50:00 PM', '17/02/2014 10:20:00 PM',
           '07/03/2014 06:10:00 AM', '02/03/2014 12:25:00 PM',
           '05/02/2014 03:20:00 AM', '31/01/2014 12:30:00 AM',
           '28/02/2014 01:25:00 PM']*10000)
t1 = np.array([np.datetime64("{}-{}-{}".format(c[:4], b, a)) for a, b, c in (s.split("/", 2) for s in t)])
....: 
10 loops, best of 3: 125 ms per loop

你的代码:

In [37]: %%timeit
from datetime import datetime
t = np.array(['21/02/2014 08:40:00 AM', '11/02/2014 10:50:00 PM',
           '07/04/2014 05:50:00 PM', '17/02/2014 10:20:00 PM',
           '07/03/2014 06:10:00 AM', '02/03/2014 12:25:00 PM',
           '05/02/2014 03:20:00 AM', '31/01/2014 12:30:00 AM',
           '28/02/2014 01:25:00 PM']*10000)
t = [datetime.strptime(tt,"%d/%m/%Y %H:%M:%S %p") for tt in t]
t = np.array(t,dtype='datetime64[us]').astype('datetime64[D]')
....: 
1 loops, best of 3: 1.56 s per loop

两者的结果虽然一样,但速度差别很大:

In [48]: t = np.array(['21/02/2014 08:40:00 AM', '11/02/2014 10:50:00 PM',
              '07/04/2014 05:50:00 PM', '17/02/2014 10:20:00 PM',
              '07/03/2014 06:10:00 AM', '02/03/2014 12:25:00 PM',
              '05/02/2014 03:20:00 AM', '31/01/2014 12:30:00 AM',
              '28/02/2014 01:25:00 PM'] * 10000)

In [49]: t1 = [datetime.strptime(tt,"%d/%m/%Y %H:%M:%S %p") for tt in t]
t1 = np.array(t1,dtype='datetime64[us]').astype('datetime64[D]')
   ....: 

In [50]: t2 = np.array([np.datetime64("{}-{}-{}".format(c[:4], b, a)) for a, b, c in (s.split("/", 2) for s in t)])

In [51]: (t1 == t2).all()
Out[51]: True

撰写回答