将 numpy.fromiter 与自定义函数一起使用
Using numpy.fromiter with custom function
我想使用 numpy.fromiter
构建一个 numpy.array(形状 (3, 2)
)
numpy 数组将由 3 个 numpy 数组组成,每个数组包含 2 个浮点数。这 3 个数组将是自定义函数的输出,但对于示例,我将使用 numpy.random.randn
.
受到 documentation 的启发,我的代码如下所示:
iterable = (np.random.randn(2) for _ in range(3))
np.fromiter(iterable, float, 3)
但是我收到以下我不理解的错误:
ValueError: setting an array element with a sequence.
我可以简单地使用 np.array([np.random.randn(2) for _ in range(3)])
(按我的意愿工作),但据我所知,它的效率会降低,因为列表是实际构建的
您的 iterable
生成一个大小为 2 的数组序列:
In [273]: for i in iterable:print(i)
[0.72823755 2.04461013]
[-0.17102804 0.14188038]
[-1.1838654 1.01953532]
但是 fromiter
需要一系列浮点数 - 一次 1 个浮点数。
Create a new 1-dimensional array from an iterable object.
但是你的列表版本生成了一个二维数组!
===
定义结构化数组数据类型:
In [283]: dt=np.dtype('f,f')
In [284]: dt
Out[284]: dtype([('f0', '<f4'), ('f1', '<f4')])
In [285]: iterable = (np.random.randn(2) for _ in range(3))
In [286]: np.fromiter(iterable,dt, 3)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-286-0301507c38c2> in <module>
----> 1 np.fromiter(iterable,dt, 3)
ValueError: setting an array element with a sequence.
使迭代器产生一个元组序列(结构化数组的正常输入是一个元组列表):
In [287]: iterable = (tuple(np.random.randn(2)) for _ in range(3))
In [288]: np.fromiter(iterable,dt, 3)
Out[288]:
array([(-0.56128544, 0.03609687), ( 0.4170706 , -1.5592302 ),
( 2.4143908 , -0.96777505)], dtype=[('f0', '<f4'), ('f1', '<f4')])
docs 明确声明
Create a new 1-dimensional array from an iterable object.
这与您显式传入 dtype
的事实一致。在你的例子中,ndarray
不是 float
,因此是错误。
你可以通过展平输入迭代来解决这个问题,例如 itertools.chain.from_iterable
:
np.fromiter(itertools.chain.from_iterable(iterable), float, 6).reshape(3, 2)
这种方法的优点是它不会构建任何中间数据结构,即使是对于单独的行也是如此。一种稍微昂贵但可能不那么神秘的方法是直接将 iterable
扩展为 itertools.chain
:
np.fromiter(itertools.chain(*iterable), float, 6).reshape(3, 2)
我想使用 numpy.fromiter
构建一个 numpy.array(形状(3, 2)
)
numpy 数组将由 3 个 numpy 数组组成,每个数组包含 2 个浮点数。这 3 个数组将是自定义函数的输出,但对于示例,我将使用 numpy.random.randn
.
受到 documentation 的启发,我的代码如下所示:
iterable = (np.random.randn(2) for _ in range(3))
np.fromiter(iterable, float, 3)
但是我收到以下我不理解的错误:
ValueError: setting an array element with a sequence.
我可以简单地使用 np.array([np.random.randn(2) for _ in range(3)])
(按我的意愿工作),但据我所知,它的效率会降低,因为列表是实际构建的
您的 iterable
生成一个大小为 2 的数组序列:
In [273]: for i in iterable:print(i)
[0.72823755 2.04461013]
[-0.17102804 0.14188038]
[-1.1838654 1.01953532]
但是 fromiter
需要一系列浮点数 - 一次 1 个浮点数。
Create a new 1-dimensional array from an iterable object.
但是你的列表版本生成了一个二维数组!
===
定义结构化数组数据类型:
In [283]: dt=np.dtype('f,f')
In [284]: dt
Out[284]: dtype([('f0', '<f4'), ('f1', '<f4')])
In [285]: iterable = (np.random.randn(2) for _ in range(3))
In [286]: np.fromiter(iterable,dt, 3)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-286-0301507c38c2> in <module>
----> 1 np.fromiter(iterable,dt, 3)
ValueError: setting an array element with a sequence.
使迭代器产生一个元组序列(结构化数组的正常输入是一个元组列表):
In [287]: iterable = (tuple(np.random.randn(2)) for _ in range(3))
In [288]: np.fromiter(iterable,dt, 3)
Out[288]:
array([(-0.56128544, 0.03609687), ( 0.4170706 , -1.5592302 ),
( 2.4143908 , -0.96777505)], dtype=[('f0', '<f4'), ('f1', '<f4')])
docs 明确声明
Create a new 1-dimensional array from an iterable object.
这与您显式传入 dtype
的事实一致。在你的例子中,ndarray
不是 float
,因此是错误。
你可以通过展平输入迭代来解决这个问题,例如 itertools.chain.from_iterable
:
np.fromiter(itertools.chain.from_iterable(iterable), float, 6).reshape(3, 2)
这种方法的优点是它不会构建任何中间数据结构,即使是对于单独的行也是如此。一种稍微昂贵但可能不那么神秘的方法是直接将 iterable
扩展为 itertools.chain
:
np.fromiter(itertools.chain(*iterable), float, 6).reshape(3, 2)