在 h5py 数据集中存储数组时,尺寸会改变吗?

When storing array in h5py dataset the dimensions is changed?

我有一个包含 3d 数组和标签的 2d 列表,我尝试使用两个数据集(数据和标签)将数据保存在 h5py 文件中,一个用于 3d 数组,另一个用于标签,但是在显示时存储 3d 数组的 'data' 数据集的内容显示的结果是 4d 数组。我创建 h4py 文件的代码:

Data_set = get3Dmatrix(ID_list) # 2d list
data = []
label = []
for i in range(len(Data_set)):
    data.append(Data_set[i][0])
    label.append(Data_set[i][1])

label = [int(i) for i in labels]#convert label to int

with h5py.File(output_path+'dataset.h5', 'w') as hf:
    hf.create_dataset('data', data=data, compression='lzf')
    hf.create_dataset('label', data=label, compression='lzf')
print("Creating h5py file is completed")
print("%s time takes in seconds" % (time.time() - start_time))

if __name__ == "__main__":
    main()

我的显示 3d 数组数据集内容的代码:

hf = h5py.File(output_path+'dataset.h5', 'r')
dt = hf.get('data')
lbl = hf.get('label')
print(dt[0:1])

我的二维列表内容如下图:

展示时得到的数组如下图:

问题是你没有比较相似的对象。备注 the content of my 2d list is like the image below 表示您希望 HDF5 文件反映您的列表或数组。但是在您的代码中,您先将数组列表转换为单个 NumPy 数组,然后再分配给 HDF5 数据集。这是相关行:

data = np.array(data)

让我们看一个最小示例,说明一些样本数据发生了什么:

arr1 = np.array([[1, 2, 3],
                 [4, 5, 6],
                 [7, 8, 9]])

arr2 = np.array([[10, 11, 12],
                 [13, 14, 15],
                 [16, 17, 18]])

现在让我们从这些单独的数组中创建一个数组列表。如您所见,列表中有两个二维数组:

L = [arr1, arr2]

print(L)

[array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]]),
 array([[10, 11, 12],
       [13, 14, 15],
       [16, 17, 18]])]

当我们转换为 NumPy 数组时会发生什么? NumPy 折叠列表结构并生成单个同构类型的 NumPy 数组,现在可以将其保存在连续的内存块中。不涉及列表指针。这正是您应该期待的。

A = np.array(L)

print(A)

array([[[ 1,  2,  3],
        [ 4,  5,  6],
        [ 7,  8,  9]],

       [[10, 11, 12],
        [13, 14, 15],
        [16, 17, 18]]])

您的输入数组有 2 个维度,因此 NumPy 将此类数组的 list 转换为具有 3 个维度的单个数组似乎是完全合理的。如果您需要二维数组,则必须指示 NumPy how 组合多个数组。例如,使用 numpy.vstack:

B = np.vstack(L)

print(B)

array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12],
       [13, 14, 15],
       [16, 17, 18]])

我可能会重复@jpp 的回答,但我需要写下这个细节以了解发生了什么。

如果我没看错的话,Data_set是一对列表(lists),每对由一个3d数组和一个字符串组成。

这个循环将它分成 2 个列表:

data = []
label = []
for i in range(len(Data_set)):
    data.append(Data_set[i][0])
    label.append(Data_set[i][1])

或者可以写成

data = [a[0] for a in Data_set]
label = [a[1] for a in Data_set]

甚至

data, label = list(zip(*Data_set))

保存时data:

hf.create_dataset('data', data=data, compression='lzf')

h5py转成数组(只能保存np.array个来源)。

看看np.array(data).shape。这将是 4 天。这看起来像是 3d 数组(相同大小)集合的逻辑数据结构。

可以将其转换回 3d 数组列表,例如list(dt).

你可以先做 data = np.concatenate(data, axis=0)。这会产生一个 3d 数组,但是你会失去原始 3d 数组之间的所有边界。