将 NumPy 数组按元素映射到多维数组中

Posted

技术标签:

【中文标题】将 NumPy 数组按元素映射到多维数组中【英文标题】:Mapping element-wise a NumPy array into an array of more dimensions 【发布时间】:2013-06-11 23:31:33 【问题描述】:

我想将numpy.array 从 NxM 映射到 NxMx3,其中三个元素的向量是原始条目的函数:

lambda x: [f1(x), f2(x), f3(x)]

但是,numpy.vectorize 之类的内容不允许更改尺寸。 当然,我可以创建一个零数组并创建一个循环 (and it is what I am doing by now),但这听起来既不是 Pythonic 也不是高效的(就像 Python 中的每个循环一样)。

有没有更好的方法来对 numpy.array 执行元素操作,为每个条目生成一个向量?

【问题讨论】:

如果 NM 明显大于 3,则在第三维上的循环对性能的影响微乎其微。使用 for 循环没有什么不符合 Python 的!使用np.vectorize 不是非常 numpythonic 或高效的。您可以尝试将f1f2f3 转换为一个接受数组并返回数组的函数。如果不知道您的函数在做什么,就不可能知道这种方法是否适合您的问题。 @Jaime 我正在循环 N 和 M,而不是 3。问题是在三个浮点数 [R,G,B] 中转换复数,所以我可以绘制一个复杂函数(请参阅链接在问题中)。 【参考方案1】:

现在我看到了您的代码,对于大多数简单的数学运算,您可以让 numpy 进行循环,这通常被称为 矢量化

def complex_array_to_rgb(X, theme='dark', rmax=None):
    '''Takes an array of complex number and converts it to an array of [r, g, b],
    where phase gives hue and saturaton/value are given by the absolute value.
    Especially for use with imshow for complex plots.'''
    absmax = rmax or np.abs(X).max()
    Y = np.zeros(X.shape + (3,), dtype='float')
    Y[..., 0] = np.angle(X) / (2 * pi) % 1
    if theme == 'light':
        Y[..., 1] = np.clip(np.abs(X) / absmax, 0, 1)
        Y[..., 2] = 1
    elif theme == 'dark':
        Y[..., 1] = 1
        Y[..., 2] = np.clip(np.abs(X) / absmax, 0, 1)
    Y = matplotlib.colors.hsv_to_rgb(Y)
    return Y

这段代码的运行速度应该比你的快。

【讨论】:

我不知道可以将子数组引用为Y[..., i]Y[i, ...]。谢谢!此操作是否有特定名称? (我在谷歌上搜索 vectorization,但它返回的内容类似于 np.vectorize。) 这是 省略号 表示法。更正了错字。 我明白了。现在我看到了一些注释:***.com/a/773472/907575 和 ***.com/questions/118370/…。【参考方案2】:

如果我正确理解您的问题,我建议您使用np.dstack:

Docstring:
Stack arrays in sequence depth wise (along third axis).

Takes a sequence of arrays and stack them along the third axis
to make a single array. Rebuilds arrays divided by `dsplit`.
This is a simple way to stack 2D arrays (images) into a single
3D array for processing.

    In [1]: a = np.arange(9).reshape(3, 3)

    In [2]: a
    Out[2]: 
    array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])

    In [3]: x, y, z = a*1, a*2, a*3  # in your case f1(a), f2(a), f3(a) 

    In [4]: np.dstack((x, y, z))
    Out[4]: 
    array([[[ 0,  0,  0],
            [ 1,  2,  3],
            [ 2,  4,  6]],

           [[ 3,  6,  9],
            [ 4,  8, 12],
            [ 5, 10, 15]],

           [[ 6, 12, 18],
            [ 7, 14, 21],
            [ 8, 16, 24]]])

【讨论】:

我会避免在之前定义x,y,z以节省内存,调用np.dstack()中的函数 +1 很好用。我接受了 Jaime 的回答,因为它更适合我的目的和一些概括。

以上是关于将 NumPy 数组按元素映射到多维数组中的主要内容,如果未能解决你的问题,请参考以下文章

numpy多维数组元素筛选

numpy多维数组元素筛选

numpy中多维数组的绝对索引

python之numpy多维数组

NumPy之:ndarray多维数组操作

Numpy:连接多维和一维数组