当前位置:   article > 正文

numpy 常用api(一)_np api

np api

numpy 常用api(二)

numpy 常用api(三)

clip

两个版本:

  • np.clip

  • 作为成员函数,x.clip

将一序列(sequence)中所有小于零的元素置零:

>>> x = np.arange(-5, 5)
>>> x
array([-5, -4, -3, -2, -1,  0,  1,  2,  3,  4])       
  • 1
  • 2
  • 3
  1. 法1,布尔索引

    >>> x<0
    array([ True,  True,  True,  True,  True, False, False, False, False, False], dtype=bool)
    >>> x[x<0] = 0
    >>> x
    array([0, 0, 0, 0, 0, 0, 1, 2, 3, 4])
    • 1
    • 2
    • 3
    • 4
    • 5
  2. 法2:np.where(三目运算),不对原始序列进行修改

    >>> x = np.where(x<0, 0, x)
    array([0, 0, 0, 0, 0, 0, 1, 2, 3, 4])
    • 1
    • 2
  3. 法3:使用clip,不对原始序列进行修改

clip的第一个参数表示目标区间最小值,第二个参数表示最大值,原始序列凡小于这个最小值的被这个最小值所替换,凡大于这个最大值的被这个最大值替换,必须指定一个参数,则另一个参数默认为。如果使用位置参数(positional argument),第一个位置表示最小值,第二个位置表示最大值,x.clip(0, 5)或者x.clip(0)。那么如何使用一个参数表示最大值呢?这时可以用named argument,即x.clip(max=5)

>>> x.clip(0)
array([0, 0, 0, 0, 0, 0, 1, 2, 3, 4])
  • 1
  • 2

我们看到,如果将所有小于零的元素置为nan,clip是无能为力的,这时只能使用布尔矩阵,或者np.where函数了:

>>> x = np.array([1., 2., -3., 4, -5.])
>>> x[x<0] = np.nan
>>> x
array([  1.,   2.,  nan,   4.,  nan])
  • 1
  • 2
  • 3
  • 4
>>> np.where(x<0, np.nan, x)
array([  1.,   2.,  nan,   4.,  nan])
  • 1
  • 2

ndarray

>>> x = np.ones(3)
>>> x 
array([1., 1., 1.])
>>> x.shape
(3,)            # 一个元素的元组
>>> y = np.ones((3, 1))
>>> y
array([[ 1.],
       [ 1.],
       [ 1.]])
>>> y.shape
(3, 1)

# 下述的运算对x=x.reshape((1, 3))也是成立的。
# (1, 3)op(3, 1)还是(3, 1)op(1, 3)最运算的结果都是以笛卡尔积的形式排列
>>> x+y
array([[ 2.,  2.,  2.],
       [ 2.,  2.,  2.],
       [ 2.,  2.,  2.]])
>>> y+x
array([[ 2.,  2.,  2.],
       [ 2.,  2.,  2.],
       [ 2.,  2.,  2.]])  
>>> x==y
array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True]], dtype=bool)         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

再来看这样一种情况:

>>> w = np.ones(3)
>>> w.shape
(3,)
>>> X = np.ones((5, 3))
>>> X
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
>>> np.dot(X, w)
array([ 3.,  3.,  3.,  3.,  3.])
>>> np.dot(X, w).shape
(5, )
>>>> X*w
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])    # 逐行再element-wise相乘    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

如果这时:

>>> w = w.reshape((3, 1))
>>> w
array([[ 1.],
       [ 1.],
       [ 1.]])
>>> np.dot(X, w) 
array([[ 3.],
       [ 3.],
       [ 3.],
       [ 3.],
       [ 3.]])           # 标准的矩阵乘法
>>> X*w
ValueError: operands could not be broadcast together with shapes (5,3) (3,1)     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

np.nan_to_num

>>> x = np.nan
>>> x
nan
>>> math.isnan(x)
True
>>> np.isnan(x)
True

>>> np.nan_to_num(x)
0.0

>>> x = np.inf
>>> x
inf
>>> np.isinf(x)
True
>>> np.nan_to_num(x)
1.7976931348623157e+308
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

场景

>>> np.log(0)
-inf
>>> 0*(-np.inf)
nan
>>> 0*np.log(0)
nan
>>> np.nan_to_num(0*np.log(0))
0.0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

0*np.log(0)直接这样的情况我们尚可避免,但如果通过变量的形式进行计算(比如y×ln(a)+(1y)×ln(1a)),以及变量会随着程序的运行其值会发生一些变化,这种情况下就很难避免了nan的出现了。而我们有知道

>>> np.nan + 10
nan 
  • 1
  • 2

nan进行运算最终的结果仍是nan,故我们需要对这样的情况进行转换,这时就需要np.nan_to_num进行转换,避免干扰。

我们引入交叉熵(cross-entropy)作为代价函数,也即:

C=jyjlnajL+(1yj)ln(1ajL)

列项求和相加,第一个反应是使用更为便捷的内积运算,也即:
C=(ylnaL+(1y)ln(1aL))

使用python语言实现:

def fn(a, y):           # a, y都是列向量
    return -(np.dot(y.transpose(), np.log(a))+np.dot((1-y), np.log(1-a)))
  • 1
  • 2

问题出现在,执行内积运算,对应位相乘有可能出现0×log(0)=nan的情况,在进行相加时会破坏整个内积运算的结果。

>>> 0*np.nan_to_num(np.log(0))
0.0
  • 1
  • 2

我们或者:

def fn(a, y):
    return -(np.dot(y.transpose(), np.nan_to_num(np.log(a)))+np.dot((1-y).transpose(), np.nan_to_num(np.log(1-a))))
  • 1
  • 2

或者:

def fn(a, y):
    return -np.sum(np.nan_to_num(y*np.log(a)+(1-y)*np.log(1-a)))
  • 1
  • 2

np.cumsum()

np.cumsum(a)函数返回一个多维数组,其shape等于a的shape

p = np.random.random(100000)
rolls = np.random.random((11, len(p)))
Alice_wins = np.cumsum(rolls < p, 0)
                                # 0,表示列向
Bob_wins = np.cumsum(rolls >= p, 0)
                                # 0,表示列向
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

首先需要说明的是,np.array() < 0,返回的是bool元素类型的多维数组。也即上述代码中的rolls < p,也即np.cumsum()的第一个参数为多维元组类型。np.cumsum(rolls < p, 0),第二个参数0表示在列的方向进行累积相加。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/792020
推荐阅读
相关标签
  

闽ICP备14008679号