H5py - using generator to create dataset - ValueError: setting an array element with a sequence
H5py - using generator to create dataset - ValueError: setting an array element with a sequence
我正在尝试通过生成器将 1D numpy 数组(展平图像)输入到 H5py 数据文件中,以创建训练和验证矩阵。
以下代码改编自一个解决方案(现在找不到),其中H5py的File
对象的create_dataset
函数的data
属性以表格形式提供数据对 np.fromiter
的调用,它有一个生成器函数作为其参数之一。
from scipy.misc import imread
import h5py
import numpy as np
import os
# Creating h5 data file
f = h5py.File('../data.h5', 'w')
# Source directory for image data
src = '/datasets/aic540/train/images/'
# Showing quantity and dimensionality of data
images = os.listdir(src)
ex_img = imread(src + images[0])
flat_img = ex_img.flatten()
print "# of images is {}".format(len(images))
print "image shape is {}".format(ex_img.shape)
print "flattened image shape is {}".format(flat_img.shape)
# Creating generator to feed in data to h5py's `create_dataset` function
gen = (imread(src + i).flatten().astype(np.int8) for i in os.listdir(src))
# Creating h5 dataset
f.create_dataset(name='training',
#shape=(59482, 1555200),
data=np.fromiter(gen, dtype=np.int8))
输出:
# of images is 59482
image shape is (540, 960, 3)
flattened image shape is (1555200,)
Traceback (most recent call last):
File "process_images.py", line 30, in <module>
data=np.fromiter(gen, dtype=np.int8))
ValueError: setting an array element with a sequence.
我在这种情况下搜索此错误时读到,问题是 np.fromiter()
需要一个列表而不是生成器函数(这似乎与名称 "fromiter" 的函数相反) implies) -- 将生成器包装在列表调用 list(gen)
中允许代码 运行 但它当然会在调用 [=14= 之前用完此列表扩展中的所有内存] 制作。
如何使用生成器将数据输入 H5py 数据文件?
如果我的方法完全错误,那么构建不适合内存的非常大的 numpy 矩阵的正确方法是什么——使用 H5py 或其他方式?
with a sequence
错误来自您尝试输入的内容 fromiter
,而不是生成器部分。
在 py3 中,range
是这样的生成器:
In [15]: np.fromiter(range(3),dtype=int)
Out[15]: array([0, 1, 2])
In [16]: np.fromiter((2*x for x in range(3)),dtype=int)
Out[16]: array([0, 2, 4])
但是如果我从一个二维数组开始(imread
生成,对吗?),然后像您一样创建一个生成器表达式:
In [17]: gen = (np.ones((2,3)).flatten().astype(np.int8) for i in range(3))
In [18]: list(gen)
Out[18]:
[array([1, 1, 1, 1, 1, 1], dtype=int8),
array([1, 1, 1, 1, 1, 1], dtype=int8),
array([1, 1, 1, 1, 1, 1], dtype=int8)]
我生成一个数组列表。
In [19]: gen = (np.ones((2,3)).flatten().astype(np.int8) for i in range(3))
In [21]: np.fromiter(gen, np.int8)
...
ValueError: setting an array element with a sequence.
np.fromiter
从迭代器创建一维数组,一次提供 'numbers' 一个,而不是分发列表或数组的东西。
无论如何,npfromiter
创建一个完整的数组;不是某种发电机。没有什么比数组 'generator'.
即使没有分块,您也可以通过 'row' 或其他切片将数据写入文件。
In [28]: f = h5py.File('test.h5', 'w')
In [29]: data = f.create_dataset(name='test',shape=(100,10))
In [30]: for i in range(100):
...: data[i,:] = np.arange(i,i+10)
...:
In [31]: data
Out[31]: <HDF5 dataset "test": shape (100, 10), type "<f4">
在您的情况下,等效于加载图像、重塑图像并立即将其写入 h5py
数据集。无需将所有图像收集到一个数组或列表中。
读取 10 行:
In [33]: data[:10,:]
Out[33]:
array([[ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[ 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.],
[ 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.],
[ 4., 5., 6., 7., 8., 9., 10., 11., 12., 13.],
[ 5., 6., 7., 8., 9., 10., 11., 12., 13., 14.],
[ 6., 7., 8., 9., 10., 11., 12., 13., 14., 15.],
[ 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.],
[ 8., 9., 10., 11., 12., 13., 14., 15., 16., 17.],
[ 9., 10., 11., 12., 13., 14., 15., 16., 17., 18.]], dtype=float32)
启用分块可能有助于处理非常大的数据集,但我没有这方面的经验。
我正在尝试通过生成器将 1D numpy 数组(展平图像)输入到 H5py 数据文件中,以创建训练和验证矩阵。
以下代码改编自一个解决方案(现在找不到),其中H5py的File
对象的create_dataset
函数的data
属性以表格形式提供数据对 np.fromiter
的调用,它有一个生成器函数作为其参数之一。
from scipy.misc import imread
import h5py
import numpy as np
import os
# Creating h5 data file
f = h5py.File('../data.h5', 'w')
# Source directory for image data
src = '/datasets/aic540/train/images/'
# Showing quantity and dimensionality of data
images = os.listdir(src)
ex_img = imread(src + images[0])
flat_img = ex_img.flatten()
print "# of images is {}".format(len(images))
print "image shape is {}".format(ex_img.shape)
print "flattened image shape is {}".format(flat_img.shape)
# Creating generator to feed in data to h5py's `create_dataset` function
gen = (imread(src + i).flatten().astype(np.int8) for i in os.listdir(src))
# Creating h5 dataset
f.create_dataset(name='training',
#shape=(59482, 1555200),
data=np.fromiter(gen, dtype=np.int8))
输出:
# of images is 59482
image shape is (540, 960, 3)
flattened image shape is (1555200,)
Traceback (most recent call last):
File "process_images.py", line 30, in <module>
data=np.fromiter(gen, dtype=np.int8))
ValueError: setting an array element with a sequence.
我在这种情况下搜索此错误时读到,问题是 np.fromiter()
需要一个列表而不是生成器函数(这似乎与名称 "fromiter" 的函数相反) implies) -- 将生成器包装在列表调用 list(gen)
中允许代码 运行 但它当然会在调用 [=14= 之前用完此列表扩展中的所有内存] 制作。
如何使用生成器将数据输入 H5py 数据文件?
如果我的方法完全错误,那么构建不适合内存的非常大的 numpy 矩阵的正确方法是什么——使用 H5py 或其他方式?
with a sequence
错误来自您尝试输入的内容 fromiter
,而不是生成器部分。
在 py3 中,range
是这样的生成器:
In [15]: np.fromiter(range(3),dtype=int)
Out[15]: array([0, 1, 2])
In [16]: np.fromiter((2*x for x in range(3)),dtype=int)
Out[16]: array([0, 2, 4])
但是如果我从一个二维数组开始(imread
生成,对吗?),然后像您一样创建一个生成器表达式:
In [17]: gen = (np.ones((2,3)).flatten().astype(np.int8) for i in range(3))
In [18]: list(gen)
Out[18]:
[array([1, 1, 1, 1, 1, 1], dtype=int8),
array([1, 1, 1, 1, 1, 1], dtype=int8),
array([1, 1, 1, 1, 1, 1], dtype=int8)]
我生成一个数组列表。
In [19]: gen = (np.ones((2,3)).flatten().astype(np.int8) for i in range(3))
In [21]: np.fromiter(gen, np.int8)
...
ValueError: setting an array element with a sequence.
np.fromiter
从迭代器创建一维数组,一次提供 'numbers' 一个,而不是分发列表或数组的东西。
无论如何,npfromiter
创建一个完整的数组;不是某种发电机。没有什么比数组 'generator'.
即使没有分块,您也可以通过 'row' 或其他切片将数据写入文件。
In [28]: f = h5py.File('test.h5', 'w')
In [29]: data = f.create_dataset(name='test',shape=(100,10))
In [30]: for i in range(100):
...: data[i,:] = np.arange(i,i+10)
...:
In [31]: data
Out[31]: <HDF5 dataset "test": shape (100, 10), type "<f4">
在您的情况下,等效于加载图像、重塑图像并立即将其写入 h5py
数据集。无需将所有图像收集到一个数组或列表中。
读取 10 行:
In [33]: data[:10,:]
Out[33]:
array([[ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[ 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.],
[ 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.],
[ 4., 5., 6., 7., 8., 9., 10., 11., 12., 13.],
[ 5., 6., 7., 8., 9., 10., 11., 12., 13., 14.],
[ 6., 7., 8., 9., 10., 11., 12., 13., 14., 15.],
[ 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.],
[ 8., 9., 10., 11., 12., 13., 14., 15., 16., 17.],
[ 9., 10., 11., 12., 13., 14., 15., 16., 17., 18.]], dtype=float32)
启用分块可能有助于处理非常大的数据集,但我没有这方面的经验。