Numpy基础(2)通用函数ufunc和面向数组编程

填坑。

二、通用函数:快速的逐元素数组函数

通用函数,也成为ufunc是一种在ndarray中进行逐元素操作的函数。某些简单函数接收一个或者多个标量数值,并且 产生一个或者多个标量结果,通用函数ufunc是对这些函数的封装。

一元通用函数:

Numpy基础(2)通用函数ufunc和面向数组编程

Numpy基础(2)通用函数ufunc和面向数组编程

二元通用函数:

Numpy基础(2)通用函数ufunc和面向数组编程

转自:https://blog.****.net/xiaoleizhanghahaha/article/details/79929990

表中没有的二元通用函数:

add 将数组的对应元素相加
subtract 在第二个数组中将第一个数组包含的元素去除
multiply 将数组对应的元素相乘
divide, floor_divide 除或者整除(忽略余数)
maximum, fmax 逐个元素计算最大值(fmax忽略NaN数值)
minimum, fmin 逐个元素计算最小值(fmin忽略NaN数值)
copysign 将第一个数组的符号值改为第二个数组的符号值

三、使用数组进行面向数组编程

利用数组表达式来替换显式循环的方法,称为向量化

向量化的数组操作会比纯Python的等价实现速度快一到两个数量级

(1)例如:想要对一些网格数据来计算sqrt(x^2 + y^2)的值。可以使用np.meshgrid函数接收两个一维数组,并且根据两个数组的所有(x, y)对生成一个二维矩阵:

>>> import numpy as np
>>> point = np.arange(-5, 5, 0.01)
>>> xs, ys = np.meshgrid(point, point)
>>> ys
array([[-5.  , -5.  , -5.  , ..., -5.  , -5.  , -5.  ],
       [-4.99, -4.99, -4.99, ..., -4.99, -4.99, -4.99],
       [-4.98, -4.98, -4.98, ..., -4.98, -4.98, -4.98],
       ...,
       [ 4.97,  4.97,  4.97, ...,  4.97,  4.97,  4.97],
       [ 4.98,  4.98,  4.98, ...,  4.98,  4.98,  4.98],
       [ 4.99,  4.99,  4.99, ...,  4.99,  4.99,  4.99]])
>>> xs
array([[-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       ...,
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99]])

现在可以用和两个坐标值相同的表达式来使用函数

>>> z = np.sqrt(xs**2 + ys**2)
>>> z
array([[7.07106781, 7.06400028, 7.05693985, ..., 7.04988652, 7.05693985,
        7.06400028],
       [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,
        7.05692568],
       [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,
        7.04985815],
       ...,
       [7.04988652, 7.04279774, 7.03571603, ..., 7.0286414 , 7.03571603,
        7.04279774],
       [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,
        7.04985815],
       [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,
        7.05692568]])

(2)将条件逻辑作为数组操作

np.where函数是三元表达式 x if condition else y 的向量化版本

>>> xarr = np.array ([1.1, 1.2, 1.3, 1.4, 1.5])
>>> yarr = np.array ([2.1, 2.2, 2.3, 2.4, 2.5])
>>> cond = np.array ([True, False, True, True, False])
>>> result = np.where(cond, xarr, yarr)
>>> result
array([1.1, 2.2, 1.3, 1.4, 2.5])

where函数的第一个参数是判断条件,如果条件成立就替换为第二个参数的相应位置,否则替换为第三个参数的相应位置

np.where函数的第二个和第三个参数并不需要是数组,可以是标量

where的典型用法是根据一个数组来生成另一个数组:
 

>>> arr = np.random.randn(4, 4)
>>> arr
array([[ 1.18168634, -1.31539927,  0.6172173 , -0.60974742],
       [ 3.73033343,  1.07285254,  0.63235803,  1.47621479],
       [ 1.96572104,  0.43233679,  1.08965316,  0.45864234],
       [-1.98120152, -0.20042831, -0.43334541, -0.31773078]])
>>> arr > 0
array([[ True, False,  True, False],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [False, False, False, False]])
>>> # 注意arr大于0直接对原数组进行了操作
>>> np.where(arr, 2, -2)
array([[2, 2, 2, 2],
       [2, 2, 2, 2],
       [2, 2, 2, 2],
       [2, 2, 2, 2]])

(3)数学和统计方法

axis=1是计算所有行,axis=0是计算所有列

>>> arr = np.random.randn(4, 5)
>>> arr
array([[-0.46094821,  0.96523928,  0.85452976,  0.47874451, -1.3856511 ],
       [ 1.04893056,  0.76919801, -1.31514516, -0.50334718,  1.90847246],
       [-0.10091909, -1.50272417, -0.32846754, -0.0460516 ,  1.27497154],
       [ 1.50370628,  0.35067036,  1.29268201, -0.17044693,  0.80954418]])
>>> arr.mean()
0.2721493984666169
>>> arr.sum()
5.4429879693323375
>>> arr.sum(axis=1)
array([ 0.45191424,  1.9081087 , -0.70319087,  3.7861559 ])
>>> arr.sum(axis=0)
array([ 1.99076953,  0.58238349,  0.50359908, -0.2411012 ,  2.60733708])
>>> arr.mean(axis=1)
array([ 0.09038285,  0.38162174, -0.14063817,  0.75723118])
>>> arr.mean(axis=0)
array([ 0.49769238,  0.14559587,  0.12589977, -0.0602753 ,  0.65183427])
sum 沿着轴向计算所有元素的累和,0长度的数组,类和为0
mean 数学平均,0长度的数组平均值为NaN
std, var 标准差和方差,可以选择自由度调整(默认分母为n)
min, max 最小值和最大值
argmin, argmax 最小值和最大值的位置
cumsum 从0开始元素累计和
cumprod 从1开始元素累积积
>>> arr
array([[-0.46094821,  0.96523928,  0.85452976,  0.47874451, -1.3856511 ],
       [ 1.04893056,  0.76919801, -1.31514516, -0.50334718,  1.90847246],
       [-0.10091909, -1.50272417, -0.32846754, -0.0460516 ,  1.27497154],
       [ 1.50370628,  0.35067036,  1.29268201, -0.17044693,  0.80954418]])
>>> arr.std()
0.9644409131451669
>>> arr.var()
0.9301462749482834
>>> arr.min()
-1.5027241675594403
>>> arr.max()
1.9084724642435182
>>> arr.argmin()
11
>>> arr.argmax()
9
>>> arr.cumsum()
array([-0.46094821,  0.50429107,  1.35882084,  1.83756534,  0.45191424,
        1.5008448 ,  2.27004281,  0.95489765,  0.45155048,  2.36002294,
        2.25910385,  0.75637968,  0.42791214,  0.38186054,  1.65683207,
        3.16053835,  3.51120871,  4.80389072,  4.63344379,  5.44298797])
>>> arr.cumprod ()
array([-4.60948212e-01, -4.44925322e-01, -3.80201931e-01, -1.82019586e-01,
        2.52215639e-01,  2.64556691e-01,  2.03496481e-01, -2.67627412e-01,
        1.34709502e-01,  2.57089375e-01, -2.59452268e-02,  3.89885194e-02,
       -1.28064631e-02,  5.89758169e-04,  7.51924879e-04,  1.13067416e-03,
        3.96493914e-04,  5.12540550e-04, -8.73609639e-05, -7.07225601e-05])

(4)布尔值数组的方法

布尔值在前面的运算中会被强制为1或者0,因此使用sum可以用于计算布尔值数组中的True的个数

布尔数组的any方法和all方法:
any方法检查数组中是否至少有一个True,而all检查是否每个值都为True

>>> b = np.array([True, False, True, True])
>>> b.all()
False
>>> b.any()
True

(5)数组的排序

仍然可以使用sort方法进行排序,多维数组需要传递排序的轴向,默认从小到大

>>> arr = np.random .randn(6)
>>> arr
array([ 0.89108809,  2.25858806, -2.44986165, -1.24294515,  0.40201138,
       -1.13466232])
>>> arr.sort()
>>> arr
array([-2.44986165, -1.24294515, -1.13466232,  0.40201138,  0.89108809,
        2.25858806])

二维数组:1代表行排序,0代表列排序,默认从小到大

>>> arr2d = np.random.randn(5, 5)
>>> arr2d
array([[ 1.05638705, -0.34053127,  2.13189608, -0.16891908, -0.19164148],
       [-0.7060822 , -0.10110753, -1.49963211, -0.73304591, -1.44895422],
       [ 0.76537315,  0.17426957, -0.49678567, -0.50147592,  0.11543533],
       [ 0.59283344, -1.17632334, -1.14794192,  0.77877637,  0.74679268],
       [ 0.07871774, -2.80155188, -0.05937185, -0.71599611,  1.2055684 ]])
>>> arr2d.sort(1)
>>> arr2d
array([[-0.34053127, -0.19164148, -0.16891908,  1.05638705,  2.13189608],
       [-1.49963211, -1.44895422, -0.73304591, -0.7060822 , -0.10110753],
       [-0.50147592, -0.49678567,  0.11543533,  0.17426957,  0.76537315],
       [-1.17632334, -1.14794192,  0.59283344,  0.74679268,  0.77877637],
       [-2.80155188, -0.71599611, -0.05937185,  0.07871774,  1.2055684 ]])
>>> arr2d.sort(0)
>>> arr2d
array([[-2.80155188, -1.44895422, -0.73304591, -0.7060822 , -0.10110753],
       [-1.49963211, -1.14794192, -0.16891908,  0.07871774,  0.76537315],
       [-1.17632334, -0.71599611, -0.05937185,  0.17426957,  0.77877637],
       [-0.50147592, -0.49678567,  0.11543533,  0.74679268,  1.2055684 ],
       [-0.34053127, -0.19164148,  0.59283344,  1.05638705,  2.13189608]])
>>> arr2d.sort()
>>> arr2d
array([[-2.80155188, -1.44895422, -0.73304591, -0.7060822 , -0.10110753],
       [-1.49963211, -1.14794192, -0.16891908,  0.07871774,  0.76537315],
       [-1.17632334, -0.71599611, -0.05937185,  0.17426957,  0.77877637],
       [-0.50147592, -0.49678567,  0.11543533,  0.74679268,  1.2055684 ],
       [-0.34053127, -0.19164148,  0.59283344,  1.05638705,  2.13189608]])
>>> 

(6)唯一值与其他集合逻辑

Numpy包含一些针对一维ndarray的基础集合操作,其中最常用的一个方法就是np.unique,返回的是数组中唯一值排序后形成的数组(去重+排序)

>>> str = np.array (['d', 's', 's', 'r', 'E', 'O', 'f', 'a'])
>>> str
array(['d', 's', 's', 'r', 'E', 'O', 'f', 'a'], dtype='<U1')
>>> np.unique(str)
array(['E', 'O', 'a', 'd', 'f', 'r', 's'], dtype='<U1')

另外一个函数是np.in1d,可以检查一个数组中的值是否在另外一个数组中,并且返回一个布尔值数组

>>> np.unique(str)
array(['E', 'O', 'a', 'd', 'f', 'r', 's'], dtype='<U1')
>>> values = np.array([6, 0, 0, 3, 2, 5, 6])
>>> values
array([6, 0, 0, 3, 2, 5, 6])
>>> np.in1d (values, [2, 3, 4, 6])
array([ True, False, False,  True,  True, False,  True])
数组的集合操作
unique(x) 计算x的唯一值,并且排序
intersect1d(x, y) 计算x和y的交集,并且排序
union1d(x, y) 计算x和y的并集,并且排序
in1d(x, y) 计算x中的元素是否包含在y中,返回一个布尔值数组
setdiff1d(x, y) 差集,在x中但是不在y中的元素
setxor1d(x, y) 异或集,在x或者y中,但是不属于x, y交集的元素