Numpy基础(2)通用函数ufunc和面向数组编程
填坑。
二、通用函数:快速的逐元素数组函数
通用函数,也成为ufunc是一种在ndarray中进行逐元素操作的函数。某些简单函数接收一个或者多个标量数值,并且 产生一个或者多个标量结果,通用函数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交集的元素 |