4

我正在尝试使用 numpy loadtxt 将 csv 文件加载到数组中。但似乎我无法正确加载日期时间。

下面演示了正在发生的事情。我做错什么了吗?

>>> s = StringIO("05/21/2007,03:27")
>>> np.loadtxt(s, delimiter=",", dtype={'names':('date','time'), 'formats':('datetime64[D]', 'datetime64[m]')})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/lib/npyio.py", line 796, in loadtxt
items = [conv(val) for (conv, val) in zip(converters, vals)]
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/lib/npyio.py", line 573, in <lambda>
  return lambda x: int(float(x))
ValueError: invalid literal for float(): 05/21/2007
4

2 回答 2

3

您还需要添加转换器,例如:

from matplotlib.dates import strpdate2num
...
np.loadtxt(s, delimiter=",", converters={0:strpdate2num('%m/%d/%Y'), 1:...}, dtype= ...

当 numpy 看到你的 datetime[64] 的 dtype 格式时,它准备输出一个 numpy.datetime64 类型的列。numpy.datetim64 是 numpy.integer 的子类,并且 loadtxt 准备将该列作为整数处理,如下所示:

def _getconv(dtype):
    typ = dtype.type
    if issubclass(typ, np.bool_):
        return lambda x: bool(int(x))
    if issubclass(typ, np.uint64):
        return np.uint64
    if issubclass(typ, np.int64):
        return np.int64
    if issubclass(typ, np.integer):
        return lambda x: int(float(x))

    ...

当它在 numpyio 的第 796 行尝试转换时:

items = [conv(val) for (conv, val) in zip(converters, vals)]

它试图用来lambda x: int(float(x))处理输入。当它这样做时,它会尝试将您的日期 (05/27/2007) 转换为浮点数并逐渐消失。上面的转换函数 strpdate2num 会将日期转换为数字表示。

于 2013-05-01T21:50:12.690 回答
2

尝试 MichealJCox 的解决方案对我不起作用。我的 numpy (1.8) 版本不接受由 给出的时间数字strpdate2num('%m/%d/%Y'),它只接受日期字符串或日期时间对象。因此,我使用了一个更复杂的转换器,它将时间字符串转换为时间数字,然后转换为 numpy 可用的 datetime 对象:

from matplotlib.dates import strpdate2num, num2date
...
convert = lambda x: num2date(strpdate2num('%m/%d/%Y')(x))
np.loadtxt(s, delimiter=",", converters={0:convert}, dtype= ...

不过,这似乎是一个庞大的解决方案。

于 2014-02-08T16:05:48.927 回答