【问题标题】:How to apply a function / map values of each element in a 2d numpy array/matrix?如何在 2d numpy 数组/矩阵中应用每个元素的函数/映射值?
【发布时间】:2017-07-24 11:55:52
【问题描述】:

给定以下 numpy 矩阵:

import numpy as np
mymatrix = np.matrix('-1 0 1; -2 0 2; -4 0 4')


matrix([[-1,  0,  1],
        [-2,  0,  2],
        [-4,  0,  4]])

以及以下函数(sigmoid/logistic):

import math
def myfunc(z):
    return 1/(1+math.exp(-z))

我想获得一个新的 NumPy 数组/矩阵,其中每个元素都是将 myfunc 函数应用于原始矩阵中的相应元素的结果。

map(myfunc, mymatrix) 失败,因为它试图将 myfunc 应用于行而不是每个元素。我尝试使用numpy.apply_along_axisnumpy.apply_over_axis,但它们也用于将函数应用于行或列,而不是逐个元素地应用。

那么如何将myfunc(z) 应用到myarray 的每个元素上得到:

matrix([[ 0.26894142,  0.5       ,  0.73105858],
        [ 0.11920292,  0.5       ,  0.88079708],
        [ 0.01798621,  0.5       ,  0.98201379]])

【问题讨论】:

    标签: numpy


    【解决方案1】:

    显然,将函数应用于元素的方法是将函数转换为向量化版本,将数组作为输入并返回数组作为输出。

    您可以使用numpy.vectorize 轻松地将您的函数转换为矢量化形式,如下所示:

    myfunc_vec = np.vectorize(myfunc)
    result = myfunc_vec(mymatrix)
    

    或单次使用:

    np.vectorize(myfunc)(mymatrix)
    

    正如@Divakar 所指出的,如果您可以像这样从头开始编写一个已经矢量化的函数(使用 NumPy 构建的 ufuncs 而不使用 numpy.vectorize),那就更好了(在性能方面):

    def my_vectorized_func(m):
        return 1/(1+np.exp(-m))  # np.exp() is a built-in ufunc
    
    my_vectorized_func(mymatrix)
    

    由于numpy.exp 已经矢量化(而math.exp 没有),整个表达式1/(1+np.exp(-m)) 将被矢量化(并且比将我的原始函数应用于每个元素更快)。

    以下完整示例产生了所需的输出:

    import numpy as np
    mymatrix = np.matrix('-1 0 1; -2 0 2; -4 0 4')
    import math
    def myfunc(z):
        return 1/(1+math.exp(-z))
    
    np.vectorize(myfunc)(mymatrix) # ok, but slow
    
    def my_vectorized_func(m):
        return 1/(1+np.exp(-m))
    
    my_vectorized_func(mymatrix) # faster using numpy built-in ufuncs
    

    【讨论】:

    • 为了提高性能,您应该使用 NumPy ufuncs - 1/(1+np.exp(-mymatrix))
    • 我修改了答案以包含一个使用内置 numpy.exp 的版本,谢谢
    【解决方案2】:

    以防万一,scipy 有一个 sigmoid 函数,您可以直接在矩阵上调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-21
      • 1970-01-01
      相关资源
      最近更新 更多