日期时间存储在 hd5 数据库中

Datetime storing in hd5 database

我有一个 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')

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

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

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

  1. np.datetime64() 个对象的列表开始,
  2. 转换为 UTC 格式的 np.datetime_as_string() 列表 对象 **请参阅第 4 项的注释
  3. 转换为 np.arraydtype='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 步,并展示了创建 np.array() 正确编码字符串的 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') ]

# 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:

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

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