python - 将返回一维数组的函数应用于 numpy 数组的所有元素

标签 python arrays numpy

假设我有一个 d 维数组,并且我想应用一个函数,该函数向每个元素返回一维数组,从而生成一个 d+1 维数组。与嵌入查找的工作原理非常相似。例如:

def f(x):
    return np.array([x * i for i in range(6)])

m = np.random.randint(0,10, (2,3,4,5))

g = np.vectorize(f)
h = np.vectorize(f, otypes=[np.ndarray])

我希望 n=g(m) 具有形状 (2,3,4,5,6) 就像我写了 4 循环,将 f 应用于 m 中的每个元素。

但是,g 会引发错误:ValueError:用序列设置数组元素。h 返回一个奇怪的数组,结尾如下:

...
[array([0, 9, 18, 27, 36, 45, 54, 63, 72]),
array([0, 5, 10, 15, 20, 25, 30, 35, 40]),
array([0, 7, 14, 21, 28, 35, 42, 49, 56]), ...,
array([0, 1, 2, 3, 4, 5, 6, 7, 8]),
array([0, 4, 8, 12, 16, 20, 24, 28, 32]),
array([0, 3, 6, 9, 12, 15, 18, 21, 24])]]]], dtype=object)

我无法改变我所期望的。

我收到了 @hpaulj 的评论,我只是找不到其他方法。

最佳答案

vectorize 添加了一个 signature 参数来执行您想要的操作。然而,它比 otypes 方法还要慢。为了完整起见,我将说明:

In [198]: def f(x):
     ...:     return np.array([x * i for i in range(6)])
In [199]: g = np.vectorize(f, signature='()->(6)')

它采用任意形状的数组,并返回一个添加了 6 维的新数组:

In [202]: g(1)
Out[202]: array([0, 1, 2, 3, 4, 5])
In [203]: g(np.array([1,2]))
Out[203]: 
array([[ 0,  1,  2,  3,  4,  5],
       [ 0,  2,  4,  6,  8, 10]])
In [204]: g(np.array([[1],[2]]))
Out[204]: 
array([[[ 0,  1,  2,  3,  4,  5]],

       [[ 0,  2,  4,  6,  8, 10]]])
<小时/>

为了更快地完成此操作,您可以使用编译的 numpy 方法来编写 f。没有一个函数可以采用 Python 函数并将其重写得更快。

对于这个f,我们可以利用 numpy 广播并编写:

In [205]: def fn(x):
     ...:     return x[...,None] * np.arange(6)
     ...: 

In [207]: fn(np.array(1))
Out[207]: array([0, 1, 2, 3, 4, 5])
In [208]: fn(np.array([1,2]))
Out[208]: 
array([[ 0,  1,  2,  3,  4,  5],
       [ 0,  2,  4,  6,  8, 10]])
In [209]: fn(np.array([[1],[2]]))
Out[209]: 
array([[[ 0,  1,  2,  3,  4,  5]],

       [[ 0,  2,  4,  6,  8, 10]]])

这里矢量化很容易。有时它需要一些聪明的思考,有时这是不可能的(特别是如果问题本质上是串行的)。有一些工具可以通过迭代解决方案生成更快的编译代码,例如 numba 和 cython。

关于python - 将返回一维数组的函数应用于 numpy 数组的所有元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51540702/

相关文章:

python - Panda如何将行分组到不同的时间桶中?

python - 从字符串中提取二维列表

php - 比较数组并在相同顺序下压缩它

python - 编写一个在 matlab 中可读的 3d numpy 数组

python - 如何将 numpy 数组从 'float64' 转换为 'float'

arrays - 传递 `OsStr` 数组的惯用方法

python - 将两个列表按元素连接成一个 n x n 矩阵

python - 从 Numpy 数组的每一行中选择一个随机样本,不包括负数

python - 计算跨数据帧的重叠时间间隔

python - 如何覆盖 Django 中的堆栈跟踪模板?