如何将日期时间值放入numpy数组中?

3

我正在学习Python,请多多包涵。我一直在尝试将一个datetime变量放入numpy数组中,但是一直无法弄清楚如何实现。后面我需要计算每个索引的时间差异,因此我不知道是否应该将datetime变量放入数组中,还是将其转换为另一种数据类型。我遇到了以下错误:

'NoneType' object does not support item assignment

我的dtype变量是否被正确构建了? 这里 没有提到datetime类型。
import numpy as np
from liblas import file

f = file.File(project_file, mode = 'r')
num_points = int(f.__len())
# dtype should be [float, float, float, int, int, datetime]
dt = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('i', 'u2'), ('c', 'u1'), ('time', 'datetime64')]
xyzict = np.empty(shape=(num_points, 6), dtype = dt)

# Load all points into numpy array
counter = 0
for p in f:
    newrow = [p.x, p.y, p.z, p.i, p.c, p.time]
    xyzict[counter] = newrow     
    counter += 1

感谢您的提前帮助。
编辑:我应该注意到,在继续之前我计划按日期对数组进行排序。 p.time 的格式如下:
>>>p.time
datetime.datetime(1971, 6, 26, 19, 37, 12, 713269)
>>>str(p.time)
'1971-06-26 19:37:12.713275'

你能否为我们贴出 project_file 的前几行以供查看?可能有更好的方法来解决这个问题,但这取决于日期格式等其他因素。 - askewchan
project_file 实际上是一个 LAS 文件。我认为应该有更好的方法。如果有助于解决问题,我会在我的帖子中添加 p.time。 - Barbarossa
哦,那个编辑有帮助:尝试使用“'datetime64[us]'”作为您的dtype。 - askewchan
哦,为此尝试将 newrow 做成元组而非列表。 - askewchan
追踪(Traceback)最近的调用如下: 在“<pyshell#98>”文件中,第3行,在<module>中, xyzict[counter] = newrow 类型错误:期望一个可读缓冲区对象。 - Barbarossa
显示剩余2条评论
1个回答

4

我不是很理解你如何从文件中获取datetime对象,或者p是干什么的,但假设你有一个元组列表(而不是列表,见上面我的评论),你可以在一个步骤中完成所有设置:

dat = [(.5, .5, .5, 0, 34, datetime.datetime(1971, 6, 26, 19, 37, 12, 713269)),
       (.3, .3, .6, 1, 23, datetime.datetime(1971, 6, 26, 19, 34, 23, 345293))]

dt = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('i', 'u2'), ('c', 'u1'), ('time', 'datetime64[us]')]

datarr = np.array(dat, dt)

然后您可以通过名称访问字段:

>>> datarr['time']
array(['1971-06-26T15:37:12.713269-0400', '1971-06-26T15:34:23.345293-0400'], dtype='datetime64[us]')

或按字段排序:

>>> np.sort(datarr, order='time')
array([ (0.3, 0.3, 0.6, 1, 23, datetime.datetime(1971, 6, 26, 19, 34, 23, 345293)),
        (0.5, 0.5, 0.5, 0, 34, datetime.datetime(1971, 6, 26, 19, 37, 12, 713269))], 
  dtype=[('x', '<f4'), ('y', '<f4'), ('z', '<f4'), ('i', '<u2'), ('c', 'u1'), ('time', '<M8[us]')])

如果我将newrow设置为元组,则每个数组索引都包含数据的6个副本。我应该将空数组的形状更改为shape =(num_points,1)吗? - Barbarossa
没错,那应该可以。实际上,将形状设置为(num_points,),不要加上1。结构化数组是一维的。"列"是"字段",元素是元组。 - askewchan
谢谢您的耐心等待。那个完美地运作了。如果我可以问一下,既然您已经向我展示了如何排序,那么我该如何遍历数组并获取时间字段的值呢? - Barbarossa
1
正如您在答案中所看到的,您可以使用datarr['time']获取所有时间。如果您想对它们进行某些操作,请不要遍历它们,只需将其应用于整个数组即可。如果您确实想要迭代,仍然可以像处理任何列表或数组一样执行for t in datarr['time']: ... - askewchan
1
太好了,再次感谢。我发现np.nditer(xyzict)正是我想要的。 - Barbarossa

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