NumPy(Numerical Python) 是 Python 语言中做科学计算的基础库。重在于数值计算,也是大部分Python科学计算库的基础,多用于在大型、多维数组上执行的数值运算。同样的数值计算,使用Numpy比直接编写Python实现代码更简洁、性能更高效。它是目前Python数值计算中最为重要的基础包。
首先我们来看一个numpy运算和普通python运算的例子:
## 一个简单的加法
# python运算
a = [1,2,3,4,5]
b = [5,4,3,2,1]
c1 = []
for i in range(5):
c1.append(a[i]+b[i])
print(c1) # [6, 6, 6, 6, 6]
# numpy 运算
c2 = np.array(a)+np.array(b)
print(c2) # [6, 6, 6, 6, 6]
# 很明显,由于Python是先循环遍历再计算,Numpy直接计算,计算数量越大越节省时间。
# 这里就会有人问了,python列表不能直接相加吗?试验一下
print(a+b) # [1, 2, 3, 4, 5, 5, 4, 3, 2, 1]
# 它的结果是这样的,并非我们想的那样,在python中[1,2,3]叫列表,而非数组
认识了numpy的作用后,我们现在来正式学习numpy吧!
a = np.array([1,2,3,4,5])
b = np.array(range(1,6))
c = np.arange(1,6) # arange与python内置方法range类似,只是前者是数组方法
print(a,b,c) # [1 2 3 4 5] [1 2 3 4 5] [1 2 3 4 5]
print(a.ndim) # 返回数组的维度数目(有几维) 1
print(a.shape) # 返回数组的维度(几行几列) (5,) 表示5行一列
print(a.dtype) # 返回数组的数据类型,数据类型有哪些,继续往下看吧 int32
print(a.size) # 返回数组索引数据元素的数目 5
d = np.array([[1,1]
,[1,1]
,[1,1]
,[1,1]])
print(d.shape) # (4,2) 表示4行两列 数组中的逗号分割行
a = np.arange(1,11)
print(a) # [ 1 2 3 4 5 6 7 8 9 10]
b = np.arange(1,11,2)
print(b) # [1 3 5 7 9] 指定了步长2
print(b.dtype) # int32 这里默认数据类型int32
c = np.arange(1,11,2,'float64')
print(c.dtype) # float64 指定了数据类型
print(c) #[1. 3. 5. 7. 9.] 浮点型,所以带了小数点 小数点后的0不显示
## np.ones(维度)
a = np.ones([1,2]) # [1,2] 表示1行两列
print(a) # [[1. 1.]]
a = np.ones([2,1,2]) # [2,1,2] 表示三个维度,第一个维度有两份,每份都有1行2列的数组,就相当于把上面的结果复制了一份
print(a) # [[[1. 1.]],[[1. 1.]]]
## np.ones_like(数组) 返回和输入的数组有着相同的维度的数组
a = np.array([[1,2],[3,4],[5,6]])
print(a.shape) # (3, 2) # 3行两列
b = np.ones_like(a) # like就是像的意思,所以就是输出一个和数组a的维度相同的数组
print(b) # 输出如下图所示
## 与ones()、ones_like()用法一致
a = np.zeros([2,2],dtype='int32')
print(a)
a = np.array([[1,2],[3,4],[5,6]]) # (3,2)
b = np.zeros_like(a)
print(b)
a = np.full([2,5],fill_value=3) # 生成2行5列的数组,填充值为3 即生成一个全是3的2行5列数组
print(a)
b = np.full_like(a,fill_value=10) # 生成与数组a相同的维度(2,5) 填充值为10
print(b)
函数名 | 说明 |
---|---|
seed(n) | 设定随机种子,只要每次的n一样,那么每次生成的随机数相同 |
rand(维度) | 返回数据在[0,1)之间,服从均匀分布 |
randn(维度) | 返回服从标准正态分布的数据 |
randint(low,high,size,dtype) | 返回[low,high}之间的随机整数 |
random | 生成[0.,1.)随机数 |
choice(array,size) | 从指定数组中产生随机数 |
shuffle(array) | 将数组随机排列 |
permutation(array) | 将数组进行随机排列,或生成数字的全排列 |
normal(loc,scale,size) | 生成服从N(loc,scale)高斯(正态)分布的数字 |
uniform(low,hight,size) | 生成[low,high)之间服从均匀分布的数字 |
np.random.seed(20)
print('--------------------------------------------rand(2,2)-------------------------------------------')
print(f'随机生成的2行2列的二维数组是:\n{np.random.rand(2,2)}' )
print('--------------------------------------------rand(2,1,3)-------------------------------------------')
print(f'随机生成的2块1行3列的三维数组是:\n{np.random.rand(2,1,3)}' )
print('--------------------------------------------randn(2,2)-------------------------------------------')
print(f'随机生成的2行2列服从标准正态分布的二维数组是:\n{np.random.randn(2,2)}')
print('--------------------------------------------randn(2,1,3)-------------------------------------------')
print(f'随机生成的2块1行3列服从标准正态分布的三维数组是:\n{np.random.randn(2,1,3)}')
print('--------------------------------------------randint(20,23)-------------------------------------------')
print(f'随机生成的在[20,23)范围内的整数是:\n{np.random.randint(20,23)}')
print('--------------------------------------------random()-------------------------------------------')
print(f'随机生成的随机数:\n{np.random.random()}')
print('--------------------------------------------choice()-------------------------------------------')
print(f'从数组[1,98,3,554,5]中生成的(2,2)随机数组:\n{np.random.choice([1,98,3,554,5],size=(2,2))}')
print(f'从数组[1,98,3,554,5]中生成的随机数:\n{np.random.choice([1,98,3,554,5],1)}')
print('--------------------------------------------shuffle()-------------------------------------------')
a = np.arange(1,5)
np.random.shuffle(a)
print(f'随机排序:\n{a}')
print('--------------------------------------------permutation()-------------------------------------------')
print(f'随机排序:\n{np.random.permutation([5,4,6,7,3,9])}')
print('--------------------------------------------normal(0,1)-------------------------------------------')
print(f'服从N(1,4)正态分布的随机数:\n{np.random.normal(1,4)}')
print('--------------------------------------------uniform(3,6,(2,2))-------------------------------------------')
print(f'服从均匀分布并在[3,6)范围内的2行2列的随机数组:\n{np.random.uniform(3,6,size=(2,2))}')
# 将2行3列全1数组 改为 3行2列的全1数组
a = np.ones([2,3])
print(f'原数组:\n{a}')
b = a.reshape([3,2])
print(f'新数组:\n{b}')
print(a.flatten()) # [1. 1. 1. 1. 1. 1.] 直接变回1维
# 加减乘除逐元素进行计算
a = np.array([1,2,3,4,5]) # (5,) 1行5列
b = np.array([1,2,3,4,5])
print(a+b)
print(a-b)
print(a*b)
print(a/b)
print(a+1) # [2 3 4 5 6]
如果两个数组的维度不一致也是可以计算的,但前提是有1个维度式一致的。
X和Y同样是3列,但行数不一致,利用广播规则,将Y沿轴复制出3行后,再进行加法运算。
函数名 | 解释 | 调用方式 |
---|---|---|
abs()、fabs() | 绝对值;非复数用fabs速度更快 | np.abs(arr)、np.fabs(arr) |
sqrt() | 开根号;数组内数值必须是非负数 | np.sqrt(arr) |
square() | 平方数 | np.square(arr) |
exp(x) | 指数e的x次方 | |
log、log10、log2 | 分别计算自然对数、底数为10、2的对数 | np.log(arr)、np.log2(arr) |
sign() | 计算各元素的正负号:正数1,负数-1,零0 | np.sign(arr) |
ceil(x) | 大于x的最小整数 | np.ceil(arr) |
floor(x) | 小于x的最大整数 | np.floor(arr) |
rint(x) | 四舍五入 | np.rint(arr) |
modf() | 将元组中的小数位和整数位以两部分独立形式返回 | np.modf(arr) |
isnan() | 是否是空值, 返回布尔类型 | np.isnan(arr) |
cos、sin、cosh、sinh、tan、tanh | 三角函数 | np.cos(arr) |
arccos、arcsin、arctan、arcsinh、arccosh、arctanh | 反三角函数 | np.arccos(arr) |
mod() | 除法取余 | np.arr(arr1,arr2) |
dot() | 数组的点积 | np.dot(arr1,arr2) |
greater、less、equal、greater_equal、less_equal、 not_equal | 比较运算(> < = >= <= !=) | np.less(arr1,arr2) |
logical_and、logical_or、logical_xor | 布尔逻辑运算(与 或 非) | np.logical_and(arr1,arr2) |
power() | 幂方计算 | np.power(arr,3) |
print(np.abs([-1,-2])) # [1 2]
print(np.sqrt([4,9,16])) # [2. 3. 4.]
print(np.square([1,2,3])) # [1 4 9]
print(np.exp([1,2,3])) # [ 2.71828183 7.3890561 20.08553692]
print(np.log10([10,100,1000])) # [1. 2. 3.]
print(np.sign([-2,0,2])) # [-1 0 1]
print(np.ceil([4.5,6.3,2.4])) # [5. 7. 3.]
print(np.floor([4.5,6.3,2.4])) # [4. 6. 2.]
print(np.mod([3,4,5],[2,2,6])) # [1 0 5] [3%2 4%2 5%6]
print(np.power([1,2,3,4],3)) # [ 1 8 27 64] [1^3 2^3 3^3 4^3]
print(np.dot([1,2,3],[1,2,3])) # 14 = 1*1+2*2+3*3
print(np.greater([1,2,3],[0,2,6])) #[ True False False]
a = np.array([3,4,6,7,8,2]) # 生成数组
print(a[1]) # 4 数组a索引为1的数即第二个数
print(a[-1]) # 2 数组a索引为-1的数即最后一个数
print(a[[0,3,4]]) # [3 7 8] 数组a索引为0,3,4的数, 输入多个索引必须将所有索引以数组形式输入
print(a[2:5]) # [6,7,8] 索引为2到4的数值
print(a[2:-1]) # [6,7,8,2] 索引为2 一直到最后一个数
print(a[2:]) # [6,7,8,2] 索引为2 一直到最后一个数
print(a[:3]) # [3,4,6] 索引为3前面的所有数据
print(a[::]) # [3,4,6,7,8,2] :: 表示输出所有数值
# 找出数组中大于5的所有数值
a = np.array([3,4,6,7,8,2])
print(a[a>5]) # [6 7 8]
a = np.random.randint(1,20,[3,5])
print(f'原数组:{a}')
print(f'取第二行的数据:\n{a[1]}')
print(f'取第二列的数据:\n{a[:,1]}')
print(f'取第二、三行数据:\n{a[1:2]}')
print(f'取第三行第三列的数据:\n{a[2,2]}')
print(f'取第1行第2列 和 第3行第4列 的 2个数值 :\n{a[[0,2],[1,3]]}')
print(f'取第1行到第3行,同时是第2列和第4列的数值 :\n{a[0:2,1:4]}')
# 把第三列大于9的数字筛选出来并修改为520
np.random.seed(20)
a = np.random.randint(1,20,[3,5])
print(a)
print('-------------输出第三列大于9的所有行-------------------')
print(a[a[:,2]>9])
print('-------------输出第三列大于9的所有数字-----------')
print(a[a[:,2]>9,2])
print('-------------将第三列大于9的数字改为520---------------')
a[a[:,2]>9,2] = 520 # 修改数据,利用索引确定需要修改的数据位置,给它赋值即可
print(a)
a = np.arange(6).reshape((3,2))
print(a) # 原数组3行2列
print(a.transpose()) # 转置后2行3列,第n行变为第n列,第n列变为第n行
a = np.arange(12).reshape((2,3,2))
print(a) # 原数组(2,3,2)
print('--------------------------------')
print(a.swapaxes(1,0)) # 将块与行转置 新数组(3,2,2)
方法 | 描述 |
---|---|
sum | 沿着轴向计算所有元素的累和,0长度的数组累和为0 |
average | 加权平均,参数可以指定weights |
prod | 所有元素的乘积 |
mean | 数学平均,0长度的数组平均值为NaN |
std,var | 标准差和方差,可以选择自由度调整(默认分母是n) |
min,max | 最小和最大值 |
argmin,argmax | 最小和最大值的位置 |
cumsum | 从0开始元素累积和 |
cumprod | 从1开始元素累积积 |
median | 中位数 |
prercentile | 0-100百分位数 |
quantile | 0-1分位数 |
print(a)
print('--------------默认 所有元素和--------------------------')
print(np.sum(a))
print('--------------axis=1代表列轴 行元素相加----------------------')
print(np.sum(a,axis=1))
print('--------------axis=0代表行轴 列元素相加-------------------')
print(np.sum(a,axis=0))
a = np.arange(2,10).reshape(2,4)
print(a)
print('-------------数组所有元素的均值---------------------')
print(np.mean(a))
print('-------------数组元素的累计和:先读行再度列---------------------')
print(np.cumsum(a))
print('-------------数组中的最小值---------------------')
print(np.min(a))
print('-------------数组中的最大值索引---------------------')
print(np.argmax(a)) # 最大值9,索引为7
a = np.arange(1,100)
print(np.percentile(a,[0,25,50,75,100])) # [ 1. 25.5 50. 74.5 99. ]
print(np.quantile(a,[0,0.25,0.5,0.75,1])) # [ 1. 25.5 50. 74.5 99. ]
a = np.array([[1,3,6],[9,3,2],[1,4,3]])
print(a>3) # 判断数组中数值是否大于3 大于3输出True,否则输出False 一一对应关系
print(np.where(a>3,520,1314)) # np.where()类似if()语句:符合条件输出520,不符合条件输出1314
a = np.array([[0,12,48],[4,18,14],[7,1,99]])
print(f'数组:\n{a}')
print('-'*30)
print(np.sort(a)) # 默认按最后的轴排序,按列排序 将每一行作为一个序列进行排序
print('-'*30)
print(np.sort(a,axis=0)) # 按行排序 将每一列作为一个序列,对序列中的数字进行排序
方法 | 描述 |
---|---|
unique(x) | 计算x的唯一值,并排序 |
intersect1d(x,y) | 计算x和y的交集,并排序 |
union1d(x,y) | 计算x和y的并集,并排序 |
in1d(x,y) | 计算x中的元素是否包含在y中,返回一个布尔值数组 |
setdiff1d(x,y) | 差集,在x中但不在y中的x元素 |
setxor1d(x,y) | 异或集,在x或y中,但不属于x、y交集的元素 |
# 1、np.unique()对数组进行去重
a = np.array([1,3,1,3,5,3,1,3,7,3,5,6])
print(np.unique(a)) # [1 3 5 6 7]
# 2、np.in1d(x,y) 检查x中的值是否在b数组中,并返回一个布尔数组: 注意:in1d 中的 1 是数字1
a = np.array([6,0,0,3,2,5,6])
b = np.array([2,3,7])
print(np.in1d(a,b)) # [ False False False True True False False]
# 3、intersect1d(x,y) 交集
print(np.intersect1d(a,b)) # [2,3]
a = np.array([1,2,3,4])
print(np.any(a>3)) # any() 只要有一个符合条件就输出True
print(np.all(a>3)) # all() 只有全部符合条件才输出True
从以下结果可以看出无论是 a= b 还是 a = b[:]切片提取数据 只要a(b)改变数值了,那么b(a)也会改变。因为这种拷贝方法,数组a和b共用一个内存地址。
a = np.array([1,2,3,4])
b = a
print(a) # [1,2,3,4]
print(b) # [1,2,3,4]
a[2] = 10
print(a) # [1,2,10,4]
print(b) # [1,2,10,4]
b[3] = 100
print(a) # [1,2,10,100]
print(b) # [1,2,10,100]
a = np.array([1,2,3,4])
c = a [1:3]
print(a) # [1,2,3,4]
print(c) # [2,3]
a[1] = 1000
print(a) # [1,1000,3,4]
print(c) # [1000,3]
c[1] = 23
print(a) # [1,1000,23,100]
print(c) # [1000,23]
a = np.array([1,2,3,4])
b = a.copy()
print(a,b) # [1 2 3 4] [1 2 3 4]
b[2] = 10
print(a,b) # [1 2 3 4] [ 1 2 10 4]
a[2] = 100
print(a,b) # [ 1 2 100 4] [ 1 2 10 4]
Numpy的学习就到这里了,下期预告:
python最最最最最重要的数据分析工具之pandas知识点总结