目录
numpy简介
numpy是Python的一种开源的数值计算扩展库。这种库可用来存储和处理大型numpy数组,比Python自身的嵌套列表结构要高效的多(该结构也可以用来表示numpy数组)。
numpy库有两个作用:
- 区别于list列表,提供了数组操作、数组运算、以及统计分布和简单的数学模型
- 计算速度快,甚至要由于python内置的简单运算,使得其成为pandas、sklearn等模块的依赖包。高级的框架如TensorFlow、PyTorch等,其数组操作也和numpy非常相似。
为什么要用numpy
现在我们来想一个场景: 购物车中存放商品的数量,依次为2,4,6,1每一个商品对应一个价格,依次是10,4,100, 29, 求一下,总价是多少?
正常思路就是:
print(2*10 + 4*4 + 6*100 + 1*29)
665
而此时可以使用两个列表分别表示商品个数和价格
l1 = [2, 4, 6, 1]
l2 = [10, 4, 100, 29]
# 天真的你就想直接相乘了,但列表没有这个功能
l1 * l2
"""
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-19-ec7519df584c> in <module>
----> 1 l1 * l2
TypeError: can't multiply sequence by non-int of type 'list'
"""
# 只能通过for循环进行
count = 0
for i in range(len(l1)):
count += l1[i] * l2[i]
print(count)
665
但是通过numpy就可以实现数组相乘
import numpy as np
a1 = np.array(l1)
a2 = np.array(l2)
print(a1)
print(a2)
[2 4 6 1]
[ 10 4 100 29]
np.sum(a1*a2) # 向量运算
665
创建numpy数组
numpy数组即numpy的ndarray对象,创建numpy数组就是把一个列表传入np.array()方法。
# 创建一维数组
arr = np.array([1,4,2])
arr
array([1, 4, 2])
# 创建二维数组
arr= np.array([[1, 2, 3], [4, 5, 6]])
arr
array([[1, 2, 3],
[4, 5, 6]])
# 创建三维的ndarray对象
print(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
[[1 2 3]
[4 5 6]
[7 8 9]]
numpy数组的常用属性
属性 | 解释 |
---|---|
T | 数组的转置 |
dtype | 数组元素的数据类型 |
size | 数组元素的个数 |
ndim | 数组的维度 |
shape | 数组的维度大小(以元组的形式) |
astype | 类型转换 |
arr = np.array([[1, 3, 5], [2, 4, 6]])
arr
array([[1, 3, 5],
[2, 4, 6]])
arr.T # 转置
array([[1, 2],
[3, 4],
[5, 6]])
arr.dtype # 查看arr的数据类型
dtype('int32')
arr.size # 查看数组元素的个数
6
arr.ndim # 查看数组的维度
2
arr.shape # 查看数组的维度大小
(2, 3)
nump数组的数据类型
类型 | 描述 |
---|---|
布尔类型 | bool_ |
整型 | int_, int8, int16, int32, int64 |
无符号整型 | uint8, uint16, uint32, uint64 |
浮点型 | float_, float16, float32, float64 |
复数型 | complex_, complex64, complex128 |
整型:
- int32只能表示(-2^31, 231-1),因为他只有32位,只能表示232个数
无符号整型:
- 只能用来存正数,不能用来存负数
补充:
- astype()方法可以修改数组的数据类型
ndarray的创建方法
方法 | 描述 |
---|---|
array() | 将列表转换为数组, 可选择显示指定dtype |
arange() | range的numpy版, 支持浮点数 |
linspace | 类似于arange(),第三个参数为数组长度 |
zeros() | 根据指定形状和detype创建全0的数组 |
ones() | 根据指定形状和detype创建全1的数组 |
empty() | 根据指定形状和detype创建空数组(随机值) |
eye() | 根据指定形状和detype创建单位矩阵 |
reshape() | 重塑形状 |
array()
arr = np.array([1,2,3])
arr
array([1, 2, 3])
arange()
- 构建0-9的ndarray数组
- 构建1-5的ndarray数组
- 构造1-19且步长为2的ndarray数组
print(np.arange(10))
[0 1 2 3 4 5 6 7 8 9]
print(np.arange(1,5))
[1 2 3 4]
print(np.arange(1,19,2))
[ 1 3 5 7 9 11 13 15 17]
linespace/logspace
- linespace: 构造一个等差数列,取头也取尾
- logspace: 构造一个等比数列
练习:
- 构造一个等差数列,取头也取尾,从0取到20,取5个数
- 构造一个等比数列,从10**0取到10**20,取5个数
print(np.linspace(0,20,5))
[ 0. 5. 10. 15. 20.]
print(np.logspace(0,20,5))
[1.e+00 1.e+05 1.e+10 1.e+15 1.e+20]
zeros/ones/eye/empty
- 构造3*4的全0 numpy数组
- 构造3*4的全1 numpy数组
- 构造3个主元的单位numpy数组
- 构造一个4*4的随机numpy数组,里面的元素是随机生成的
print(np.zeros((3,4),dtype=float))
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
print(np.ones((3,4), dtype=int))
[[1 1 1 1]
[1 1 1 1]
[1 1 1 1]]
print(np.eye(3))
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
print(np.empty((4,4)))
[[6.23042070e-307 1.89146896e-307 1.37961302e-306 1.05699242e-307]
[8.01097889e-307 1.78020169e-306 7.56601165e-307 1.02359984e-306]
[1.33510679e-306 2.22522597e-306 1.60220393e-306 1.60219170e-306]
[1.86921143e-306 1.11261434e-306 2.22522596e-306 0.00000000e+000]]
reshape
arr = np.ones((2, 2), dtype=int)
arr
array([[1, 1],
[1, 1]])
arr.reshape(4,1)
array([[1],
[1],
[1],
[1]])
numpy索引和切片
切分numpy数组类似于列表的切割,但是与列表的切割不同的是,numpy数组的切割涉及到行和列的切割,但是两者切割的方式都是从索引0开始,并且取头不取尾。
arr = np.array([i for i in range(1,49)]).reshape(6,8)
arr
array([[ 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, 28, 29, 30, 31, 32],
[33, 34, 35, 36, 37, 38, 39, 40],
[41, 42, 43, 44, 45, 46, 47, 48]])
# 取出所有元素
print(arr[:,:])
[[ 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 28 29 30 31 32]
[33 34 35 36 37 38 39 40]
[41 42 43 44 45 46 47 48]]
# 取出第2-4行的所有元素
print(arr[1:4,:])
[[ 9 10 11 12 13 14 15 16]
[17 18 19 20 21 22 23 24]
[25 26 27 28 29 30 31 32]]
# 取出第1-3列的数据
print(arr[:,:3])
[[ 1 2 3]
[ 9 10 11]
[17 18 19]
[25 26 27]
[33 34 35]
[41 42 43]]
# 取出第一列的前三个元素
print(arr[(0,1,2),0])
[ 1 9 17]
# 取出第三行后3个元素
print(arr[2,(-3,-2,-1)])
[22 23 24]
# 取出大于20的元素, 返回一个数组
print(arr[arr > 20])
[21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
45 46 47 48]
# numpy数组按运算符取元素的原理,即通过arr > 20生成一个布尔numpy数组
print(arr > 20)
[[False False False False False False False False]
[False False False False False False False False]
[False False False False True True True True]
[ True True True True True True True True]
[ True True True True True True True True]
[ True True True True True True True True]]
numpy数组元素替换
numpy数组元素的替换,类似于列表元素的替换,并且numpy数组也是一个可变类型的数据,即如果对numpy数组进行替换操作,会修改原numpy数组的元素,所以下面我们用.copy()方法举例numpy数组元素的替换
arr
array([[ 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, 28, 29, 30, 31, 32],
[33, 34, 35, 36, 37, 38, 39, 40],
[41, 42, 43, 44, 45, 46, 47, 48]])
# 取第一行的所有元素,并且让第一行的元素都为0
arr1 = arr.copy()
arr1[0, :] = 0
arr1
array([[ 0, 0, 0, 0, 0, 0, 0, 0],
[ 9, 10, 11, 12, 13, 14, 15, 16],
[17, 18, 19, 20, 21, 22, 23, 24],
[25, 26, 27, 28, 29, 30, 31, 32],
[33, 34, 35, 36, 37, 38, 39, 40],
[41, 42, 43, 44, 45, 46, 47, 48]])
# 取所有被5整除的元素,并且赋值为0
arr2 = arr.copy()
arr2[arr2 % 5 == 0] = 0
print(arr2)
[[ 1 2 3 4 0 6 7 8]
[ 9 0 11 12 13 14 0 16]
[17 18 19 0 21 22 23 24]
[ 0 26 27 28 29 0 31 32]
[33 34 0 36 37 38 39 0]
[41 42 43 44 0 46 47 48]]
# 对numpy数组清零
arr2[:,:] = 0
print(arr2)
[[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]]
numpy数组的合并
- hstack((arr1, arr2,...)): 合并ndarray数组的行, 此时要求合并的数据要有相同的行, 其中hstack的h表示horizontal水平的
- vstack((arr1, arr2,...)): 合并ndarray数组的列, 此时要求合并的数据要有相同的列,其中vstack的v表示vertical垂直的
- concatenate((arr1, arr2,...), axis): 合并两个numpy数组,其中axis=1表示合并两个numpy数组的行, axis=0表示合并两个numpy数组的列
arr1 = np.array([i for i in range(1,7)]).reshape(3,2)
arr1
array([[1, 2],
[3, 4],
[5, 6]])
arr2 = np.array([i for i in range(7,13)]).reshape(3,2)
arr2
array([[ 7, 8],
[ 9, 10],
[11, 12]])
# 合并三个numpy数组的行
print(np.hstack((arr1, arr2, arr1)))
print('*'*50)
print(np.concatenate((arr1,arr2,arr1), axis=1))
[[ 1 2 7 8 1 2]
[ 3 4 9 10 3 4]
[ 5 6 11 12 5 6]]
**************************************************
[[ 1 2 7 8 1 2]
[ 3 4 9 10 3 4]
[ 5 6 11 12 5 6]]
# 合并两个数组的列
print(np.vstack((arr2,arr1)))
print('*'*50)
print(np.concatenate((arr2,arr1), axis=0))
[[ 7 8]
[ 9 10]
[11 12]
[ 1 2]
[ 3 4]
[ 5 6]]
**************************************************
[[ 7 8]
[ 9 10]
[11 12]
[ 1 2]
[ 3 4]
[ 5 6]]
numpy数组的运算
运算符 | 说明 |
---|---|
+ | 两个numpy数组对应元素相加 |
- | 两个numpy数组对应元素相减 |
* | 两个numpy数组对应元素相乘 |
/ | 两个numpy数组对应元素相除,如果都是整数则取商 |
% | 两个numpy数组对应元素相除后取余数 |
**n | 单个numpy数组每个元素都取n次方,如**2:每个元素都取平方 |
arr1
array([[1, 2],
[3, 4],
[5, 6]])
arr2
array([[ 7, 8],
[ 9, 10],
[11, 12]])
arr1 + arr2
array([[ 8, 10],
[12, 14],
[16, 18]])
arr1 * arr2
array([[ 7, 16],
[27, 40],
[55, 72]])
arr1 * 3
array([[ 3, 6],
[ 9, 12],
[15, 18]])
arr2 ** 2
array([[ 49, 64],
[ 81, 100],
[121, 144]], dtype=int32)
numpy数组运算函数
- 一元函数
函数 | 功能 |
---|---|
abs、fabs | 分别是计算整数和浮点数的绝对值 |
sqrt | 计算各元素的平方根 |
square | 计算各元素的平方 |
exp | 计算各元素的指数e**x |
log | 计算自然对数 |
sign | 计算各元素的正负号 |
ceil | 计算各元素的ceiling值 |
floor | 计算各元素floor值,即小于等于该值的最大整数 |
rint | 计算各元素的值四舍五入到最接近的整数,保留dtype |
modf | 将数组的小数部分和整数部分以两个独立数组的形式返回,与 |
isnan | 计算各元素的是否有nan |
isinf | 表示那些元素是无穷的布尔型数组 |
cos,sin,tan | 普通型和双曲型三角函数 |
- 二元函数
函数 | 功能 |
---|---|
add | 将数组中对应的元素相加 |
subtract | 从第一个数组中减去第二个数组中的元素 |
multiply | 数组元素相乘 |
divide、floor_divide | 除法或向下圆整除法(舍弃余数) |
power | 对第一个数组中的元素A,根据第二个数组中的相应元素B计算A**B |
maximum,fmax | 计算最大值,fmax忽略NAN |
miximum,fmix | 计算最小值,fmin忽略NAN |
mod | 元素的求模计算(除法的余数) |
补充:
- 浮点数的特殊值
- nan(Not a Number): 不等于任何浮点数(nan != nan)
- inf(infinity):比任何浮点数都大
数学统计方法
函数 | 功能 |
---|---|
sum | 求和 |
cumsum | 求前缀和 |
mean | 求平均数 |
std | 求标准差 |
var | 求方差 |
min | 求最小值 |
max | 求最大值 |
argmin | 求最小值索引 |
argmax | 求最大值索引 |
随机数
随机数生成函数在np.random的子包当中
函数 | 功能 |
---|---|
rand | 给定形状产生随机数组(0到1之间的数) |
randint | 给定形状产生随机整数 |
chocie | 给定形状产生随机选择 |
shuffle | 与random.shuffle相同 |
uniform | 给定形状产生随机数组 |