数组运算¶
数组运算,极大地拓展了我们使用数组来解决实际问题的能力,不需要学习复杂的数学知识,在日常的使用中,跟普通的运算并无太大差别。
1 数组与标量之间的运算¶
通常我们把**单独的数叫做标量**,数组可以直接与标量进行计算,计算逻辑会自动传播到数组的全部元素中。我们举几个简单的例子:
# 数组与标量的加法运算
import numpy as np
arr = np.array([[1,2,3], [4,5,6]])
arr + 5
Out:
array([[ 6, 7, 8],
[ 9, 10, 11]])
# 数组与标量的乘法运算
arr * 2
Out:
array([[ 2, 4, 6],
[ 8, 10, 12]])
# 数组与标量的除法运算,求数组中每个元素的倒数
1 / arr
Out:
array([[1. , 0.5 , 0.33333333],
[0.25 , 0.2 , 0.16666667]])
# 数组与标量的乘方运算,求数组中每个元素的平方
arr ** 2
Out:
array([[ 1, 4, 9],
[16, 25, 36]], dtype=int32)
# 求数组中每个元素的算术平方根
arr ** 0.5
Out:
array([[1. , 1.41421356, 1.73205081],
[2. , 2.23606798, 2.44948974]])
2 数组的通用函数运算¶
所谓的通用函数ufunc
,就是能够对数组中的每个元素进行微操,也就是元素级的函数运算。
2.1 四则运算¶
最简单的通用函数就是数组与数组的四则运算。但是在进行数组的四则运算的时候,我们需要保证二者的维数一样:
# 数组的减法:
arr - arr
Out:
array([[0, 0, 0],
[0, 0, 0]])
# 数组的乘法:
arr * arr
Out:
array([[ 1, 4, 9],
[16, 25, 36]])
需要注意的是,这里的乘法是表示数组对应位置的元素相乘,并不是高等数学上的矩阵的乘法。当然了数组的加法和除法规则都类似,这里不一一举例了。总的来讲,Numpy针对常见的数组之间的运算,做了一些函数封装,一起看一下:
函数 | 说明 |
---|---|
add , subtract , multiply , divide |
算术四则运算,分别对应加、减、乘、除 |
2.2 一元函数¶
对数组求三角函数、求平均、求幂运算等均输入一元函数的范畴,我们把常用的一元函数列举如下,供大家查阅:
函数 | 说明 |
---|---|
abs ,fabs |
计算绝对值,对于非负数值,可以使用更快的fass |
sqrt ,square ,exp |
求个元素的平方根、平方、指数ex |
log ,log10 ,log2 ,log1p |
分别计算自然对数(底数为e)、底数为10的log、底数为2的log、log(1+x) |
sign |
计算各元素的正负号:1(整数)、0(零)、-1(负数) |
ceil |
计算各元素的、大于等于该值的最小整数 |
floor |
计算各元素的、大于等于该值的最大整数 |
rint |
将各元素值四舍五入到最接近的整数,并保留dtype |
modf |
把数组的小数和整数部分以两个独立的数组分别返回 |
isnan |
判断各元素是否为空NaN ,返回布尔型 |
cos ,cosh ,sin ,sinh ,tan ,tanh |
普通型和双曲型三角函数 |
# 创建一个符合均值为5标准差为10的正态分布数组
arr_rnd = np.random.normal(5, 10, (3, 4))
arr_rnd
Out:
array([[19.03116154, 13.58954268, 11.93818701, 4.85006153],
[ 0.57122874, 4.33719914, 8.67773155, 10.15552974],
[ 7.04757778, 6.98288594, 10.60656035, 17.95555988]])
# 对数组进行四舍五入运算。需要注意的是,结果数组仍然保留了输入数组的dtype属性
np.rint(arr_rnd)
Out:
array([[19., 14., 12., 5.],
[ 1., 4., 9., 10.],
[ 7., 7., 11., 18.]])
2.3 二元函数¶
把常用的二元函数列举如下,供大家查阅:
函数 | 说明 |
---|---|
maximum ,fmax |
计算元素级的最大值,fmax 自动忽略空值NaN |
minimum ,fmin |
计算元素级的最小值,fmin 自动忽略空值NaN |
greater ,greater_equal |
执行元素级的比较,生产布尔型数组。效果相当于> ,≥ |
less ,less_equal |
执行元素级的比较,生产布尔型数组。效果相当于< ,≤ |
equal ,not_equal |
执行元素级的比较,生产布尔型数组。效果相当于== ,!= |
logical_and ,logical_or ,logic_xor |
执行元素级的逻辑运算,相当于执行运算符& 、| 、^ |
这里要提醒的是,数组运算本身并不复杂,只是套用公式的过程。但是在使用之前,大家千万要注意数组中是否有空值,空值的存在可能会导致运算结果错误甚至是报错。判断数组是否存在空值,需要使用isnan
函数。
# 利用随机函数,产生2个数组
x = np.random.normal(5, 10, (3,1))
y = np.random.normal(5, 10, (3,1))
x
Out: array([ 9.5336068 , 8.31969942, 15.20601081])
y
Out: array([22.52827938, 3.01609475, 9.03514098])
# 计算,比较元素级的最大值
np.maximum(x,y)
Out: array([22.52827938, 8.31969942, 15.20601081])
# 计算,比较元素级的最小值
np.minimum(x,y)
Out: array([9.5336068 , 3.01609475, 9.03514098])
# 计算,执行元素级的比较
np.greater(x,y)
Out: array([False, True, True])
3 数组的聚合函数运算¶
聚合函数是指对一组值(比如一个数组)进行操作,返回一个单一值作为结果的函数,比如求数组所有元素之和就是聚合函数。常见的聚合函数有:求和,求最大最小,求平均,求标准差,求中位数等。
常用的聚合函数一览表:
函数 | 说明 |
---|---|
sum |
求和运算 |
cumsum |
累积求和运算 |
min |
求最小值 |
max |
求最大值 |
mean |
求均值 |
median |
求中位数 |
var |
求方差 |
std |
求标准差 |
在实际工程中,我们通常把若干个样本组成一个数组进行运算。二维数组的垂直方向定义为**axis 0
****轴,水平方向为****axis 1
****轴**。当我们在对Numpy
进行运算时,我们把axis=0
指定为垂直方向的计算,axis=1
指定为水平方向的运算。
# 利用自带的随机数生成函数生成5位选手的评委打分结果,一共有7位评委。打分结果用5×7大小的数组表示
votes = np.random.randint(1, 10, (5, 7))
votes
Out: array([[8, 6, 4, 1, 6, 1, 5],
[7, 6, 1, 9, 2, 1, 5],
[9, 6, 8, 9, 3, 5, 4],
[8, 5, 8, 4, 7, 9, 7],
[6, 2, 1, 2, 1, 8, 3]])
# 总分-最高分-最低分,再求平均,即可求得最终结果
(np.sum(votes, axis=1)-np.max(votes, axis=1)-np.min(votes, axis=1))/5
Out: array([4.4, 4.2, 6.4, 7. , 2.8])
3.1 利用Numpy
实现条件判断¶
条件判断是在计算领域非常常见的一种场景。例如我希望对上面产生的arr_rnd
的数据网格进行判断,如果数据元素小于等于5,则替换成NaN
。其实利用np.where
函数轻松实现:
# where 函数中输入3个参数,分别是判断条件、为真时的值,为假时的值
# 在Numpy中,空值是一种新的数据格式,我们用np.nan产生空值
np.where(arr_rnd<5, np.nan, arr_rnd)
Out: array([[19.03116154, 13.58954268, 11.93818701, nan],
[ nan, nan, 8.67773155, 10.15552974],
[ 7.04757778, 6.98288594, 10.60656035, 17.95555988]])
如果还是找不到合适的函数来实现自己的目的,那不妨自己写一个,也很简单。我们只需要利用frompyfunc
函数,将计算单元素的函数转换成,能对数组的每个元素进行操作的函数即可。
假设某淘宝店做批发生意,店里的人气产品A原价为20元。购买100件及以上,打6折;购买50件及以上,不到100件,打8折;购买10件及以上,不满50件,打9折;不满10件不打折。已知某天5位客户的具体购买量,求当天的营业额。方法有很多,那么今天这里给大家推荐一种基于数组的计算方法:
# 定义函数,购买x件订单,返回订单金额
def order(x):
if x>=100:
return 20*0.6*x
if x>=50:
return 20*0.8*x
if x>=10:
return 20*0.9*x
return 20*x
# frompyfunc函数有三个输入参数,分别是待转化的函数、函数的输入参数的个数、函数的返回值的个数
income = np.frompyfunc(order, 1, 1)
# order_lst 为5位顾客的下单量
order_lst = [600, 300, 5, 2, 85]
# 计算当天的营业额
np.sum(income(order_lst))
Out: 12300.0
本节涉及的函数较多,在学习中大家切勿以死记硬背的心态介入学习。在数据分析学习阶段,应该是以理解加实践为主,至于函数太多记不住,那就交给时间去解决吧,用多了自然就记住了。对于偏门的函数,在应用的时候查阅即可。
创建日期: 2021年9月12日 05:55:32