就地改组多个HDF5数据集

时间:2015-06-22 10:20:59

标签: python numpy hdf5 h5py

我有多个HDF5数据集保存在同一个文件my_file.h5中。这些数据集具有不同的维度,但第一维中的观察数量相同:

features.shape = (1000000, 24, 7, 1)
labels.shape = (1000000)
info.shape = (1000000, 4)

将信息/标签数据正确连接到每组要素非常重要,因此我希望使用相同的种子来混洗这些数据集。此外,我想把它们洗掉,而不是将它们完全加载到内存中。是否可以使用numpy和h5py?

3 个答案:

答案 0 :(得分:1)

在磁盘上重排阵列将非常耗时,因为这意味着您已在hdf5文件中分配新阵列,然后以不同的顺序复制所有行。如果要避免使用PyTables或h5py将所有数据一次性加载到内存中,可以迭代行(或使用行块)。

另一种方法可能是保持您的数据不变,只需将新行号映射到单独数组中的旧行号(您可以将其完全加载到RAM中,因为对于您的数组大小,它只有4MB )。例如,要改组一个numpy数组x = np.random.rand(5) idx_map = numpy.arange(x.shape[0]) numpy.random.shuffle(idx_map)

x[idx_map[2]] # equivalent to x_shuffled[2]
x[idx_map]    # equivament to x_shuffled[:], etc.

然后,您可以使用advanced numpy indexing访问随机数据

[2015-06-22 14:23:30,745: INFO/Worker-4] Starting new HTTPS connection (1): mandrillapp.com
[2015-06-22 14:23:31,521: INFO/Worker-4] Starting new HTTPS connection (1): mandrillapp.com
[2015-06-22 14:23:32,162: INFO/Worker-4] Starting new HTTPS connection (1): mandrillapp.com

这也适用于保存到hdf5的数组。当然,与在磁盘上编写混洗数组相比,会有一些开销,但根据您的使用情况,它可能就足够了。

答案 1 :(得分:1)

np.arange(1000000)中这样的混洗数组是直截了当的

创建大型索引(shuffle features = features[I, ...] labels = labels[I] info = info[I, :] )并索引数组

labels[I]

这不是一个现场操作。 labelsfeatures[I,...] = features 的副本,而不是切片或视图。

替代

I

在表面看起来就像是一个就地操作。我怀疑它是在C代码中。它必须被缓冲,因为ufunc值不能保证是唯一的。事实上,对于无缓冲操作,有一种特殊的.at h5py方法。

但请看一下labels[I]关于这种类似的花式索引的说法':

http://docs.h5py.org/en/latest/high/dataset.html#fancy-indexing

List selections may not be empty Selection coordinates must be given in increasing order Duplicate selections are ignored Very long lists (> 1000 elements) may produce poor performance 选择已实施,但有限制。

I

根据定义,您的混乱labels[I] = ...不是递增的顺序。它非常大。

此外,我还没有看到任何关于在左侧{{1}}使用这种精美索引的信息。

答案 2 :(得分:0)

import numpy as np
import h5py

data = h5py.File('original.h5py', 'r')

with h5py.File('output.h5py', 'w') as out:
    indexes = np.arange(data['some_dataset_in_original'].shape[0])
    np.random.shuffle(indexes)
    for key in data.keys():
        print(key)
        feed = np.take(data[key], indexes, axis=0)
        out.create_dataset(key, data=feed)