首页 > 解决方案 > 日期时间存储在 hd5 数据库中

问题描述

我有一个 np.datetime64 数据列表,如下所示:

times =[2015-03-26T16:02:42.000000Z,
 2015-03-26T16:02:45.000000Z,...]

type(times) returns list

type(times[1]) returns obspy.core.utcdatetime.UTCDateTime

现在,我了解到 h5py 不支持日期时间数据。

我尝试了以下方法:

time_str = [n.encode("ascii", "ignore") for n in time_str]
time_str = [str(s) for s in time_str]

type(time_str[1]) returns bytes

我可以创建数据集并将这些日期时间值存储为字符串

但是,在尝试创建数据集时,出现以下错误:

with h5py.File('data_ML.hdf5', 'w') as f:
           f.create_dataset("time", data=time_str,maxshape=(None),chunks=True, dtype='str')

TypeError: No conversion path for dtype: dtype('<U')

我在哪里搞砸了/是否有另一种方法可以按原样存储这些值,以便以后提取它们?

标签: pythondatetimeh5py

解决方案


好的,我们开始吧。我无法让你们中的一些代码一起工作(也许您遗漏了一些步骤,或者更改了变量名?)。而且,我无法得到obspy.core.utcdatetime.UTCDateTime您拥有的对象。

所以我创建了一个执行以下操作的示例:

  1. np.datetime64()从对象列表开始,
  2. 转换为np.datetime_as_string()UTC 格式的对象列表 **参见第 4 项的注释
  3. 转换为np.array一个dtype='S30'
  4. 注意:我包括第 2 步来复制您的数据。请参阅以下部分以获取更简单的版本

下面的代码:

times =[np.datetime64('2015-03-26T16:02:42.000000'),
        np.datetime64('2015-03-26T16:02:45.000000'),
        np.datetime64('2015-03-26T16:02:48.000000'),
        np.datetime64('2015-03-26T16:02:55.000000') ]

utc_times = [ np.datetime_as_string(n,timezone='UTC') for n in times ]
  
utc_str_arr = np.array(utc_times,dtype='S30')   

with h5py.File('data_ML.hdf5', 'w') as f:
     f.create_dataset("time", data=utc_str_arr,maxshape=(None),chunks=True)

如果您从np.datetime64()对象开始,并且没有(并且不需要或不想要)字符串对象的中间列表(utc_times我的代码中的变量),则可以简化该过程。下面的方法跳过了上面的第 2 步,并展示了 2 种创建np.array()正确编码字符串的方法。

下面的代码:

times =[np.datetime64('2015-03-26T16:02:42.000000'),
        np.datetime64('2015-03-26T16:02:45.000000'),
        np.datetime64('2015-03-26T16:02:48.000000'),
        np.datetime64('2015-03-26T16:02:55.000000') ]

# Create empty array with defined size and 'S#' dtype, then populate with for loop:
utc_str_arr1 = np.empty((len(times),),dtype='S30')
for i, n in enumerate(times):
    utc_str_arr1[i] = np.datetime_as_string(n,timezone='UTC')

# -OR- Create array and populate using loop comprehension:
utc_str_arr2 = np.array( [np.datetime_as_string(n,timezone='UTC').encode('utf-8') for n in times] )

with h5py.File('data_ML.hdf5', 'w') as f:
     f.create_dataset("time1", data=utc_str_arr1,maxshape=(None),chunks=True)
     f.create_dataset("time2", data=utc_str_arr2,maxshape=(None),chunks=True)

两种方法的最终结果看起来都相似(第二种方法创建 2 个相同的数据集)。
来自HDFView的图像:
https://stackoverflow.com/a/46921593/10462884

读取数据:
根据 2021 年 8 月 2 日评论中的请求,这里是从 HDF5 中提取数据并创建 Pandas 时间戳对象(然后保存到数据帧)的代码。首先,读取数据集中的字节字符串并将其转换为 NumPy Unicode 字符串.astype()pd.to_datetime()然后使用参数将字符串转换为 Pandas 时间戳对象format=

import h5py
import numpy as np
import pandas as pd

with h5py.File('data_ML.hdf5', 'r') as h5f:
    ## returns a h5py dataset object:
    dts_ds = h5f["time"]
    longest_word=len(max(dts_ds, key=len))
    
    ## returns an array of byte strings representing np.datetime64:
    ## .astype() used to convert byte strings to unicode
    dts_arr = dts_ds[:].astype('U'+str(longest_word))

    ## create a new array to hold Pandas datetime objects
    ## then loop over first array to convert and populate new array
    pd_dts_arr = np.empty((dts_arr.shape[0],),dtype=object)
    for i, dts in enumerate(dts_arr):    
        pd_dts_arr[i] = pd.to_datetime(dts, format='%Y-%m-%dT%H:%M:%S.%fZ')
        
    dts_df = pd.DataFrame(pd_dts_arr)

有很多方法可以使用原生 Python、NumPy 和 Pandas 对象来表示日期和时间。可以在此答案中找到有关使用它们的更多详细信息: Converting between datetime, Timestamp and datetime64


推荐阅读