一、什么是numpy?
一个在Python中做科学计算的基础库,重在数值计算,也是大部分Python 科学计算库的基础库,多用于大型、多维数组上执行数值运算。
二、numpy常用操作
创建数组(矩阵)
# 1.array方法创建
a = np.array([1,2,3,4,5])
b = np.array(range(1,6))
# 2.arange方法创建
c = np.arange(1,6)
a,b,c内容相同,生成的均为array类型的数组。但要注意arange和range的区别,两者使用方法类似。
查看数组的类名及数据的类型
# 查看数组的类名
In [1]:a = np.array([1,2,3,4,5])
In [2]:type(a)
Out[2]: numpy.ndarray
# 查看数据的类型
In [3]: a.dtype
Out[3]: dtype('int32')
数据类型的操作
- 指定创建的数组的数据类型
In [9]: a=np.array([1,0,1,0],dtype=np.bool) # 或者使用dtype='?'
In [10]: a
Out[10]: array([ True, False, True, False], dtype=bool)
- 修改数组的数据类型
In [11]: a.astype('i1') # 或者使用a.astype(np.int8)
Out[11]: array([1, 0, 1, 0], dtype=int8)
- 修改浮点型的小数位数
In [16]: t = np.array([random.random() for i in range(10)])
In [17]: t
Out[17]:
array([0.38585747, 0.36921982, 0.69662902, 0.62439023, 0.33241034,
0.69588703, 0.29398491, 0.27252776, 0.00847748, 0.0959942 ])
In [18]: np.round(t,2)
Out[18]: array([0.39, 0.37, 0.7 , 0.62, 0.33, 0.7 , 0.29, 0.27, 0.01, 0.1 ])
- numpy中常见的更多数据类型
类型 | 类型代码 | 说明 |
---|---|---|
int8、uint8 | i1、u1 | 有符号和无符号的8位(1个字节)整型 |
int16、uint16 | i2、u2 | 有符号和无符号的16位(2个字节)整型 |
int32、uint32 | i4、u4 | 有符号和无符号的32位(4个字节)整型 |
int64、uint64 | i8、u8 | 有符号和无符号的64位(8个字节)整型 |
float16 | f2 | 半精度浮点数 |
float32 | f4或f | 标准的单精度浮点数。与C的float兼容 |
float64 | f8或d | 标准的双精度浮点数。与C的double和Python的float对象兼容 |
float128 | f16或g | 扩展精度浮点数 |
complex64、complex128、complex256 | c8、c16、c32 | 分别用两个32位、64位或128位浮点数来表述的复数 |
bool | ? | 存储True和False的布尔类型 |
数组的形状
In [19]: a=np.array([[3,4,5,6,7,8],[4,5,6,7,8,9]])
In [20]: a
Out[20]:
array([[3, 4, 5, 6, 7, 8],
[4, 5, 6, 7, 8, 9]])
- 查看数组的形状
In [21]: a.shape
Out[21]: (2, 6)
- 修改数组的形状
(1)reshape方法
reshape函数是numpy中一个很常用的函数,作用是在不改变矩阵的数值的前提下修改矩阵的形状。
In [22]: y =np.arange(24).reshape((2,3,4))
In [23]: y
Out[23]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
一维数组与二维数组的区分
# 一维数组
In [5]: y.reshape((24,))
Out[5]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23])
# 二维数组
# (1)24行1列
In [6]: y.reshape((24,1))
Out[6]:
array([[ 0],
[ 1],
[ 2],
[ 3],
[ 4],
[ 5],
[ 6],
[ 7],
[ 8],
[ 9],
[10],
[11],
[12],
[13],
[14],
[15],
[16],
[17],
[18],
[19],
[20],
[21],
[22],
[23]])
# (1)1行24列
In [7]: y.reshape((1,24))
Out[7]:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])
(2)flatten方法
flatten是numpy.ndarray.flatten的一个函数,即返回一个一维数组。
flatten只能适用于numpy对象,即array或者mat,普通的list列表不适用!
a.flatten():a是个数组,a.flatten()就是把a降到一维,默认是按行的方向降 。
a.flatten().A:a是个矩阵,降维后还是个矩阵,矩阵.A(等效于矩阵.getA())变成了数组。
In [8]: y.flatten()
Out[8]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23])
数组的计算
In [10]: a =np.arange(24).reshape((4,6))
In [11]: a
Out[11]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
与数值进行运算
数组与数值的运算:数值与数组各个元素执行相应运算。
这是numpy的广播机制造成的,在运算过程中,加减乘除的值被广播到所有的元素上面。
- 数组与数值相加
In [12]: a+2
Out[12]:
array([[ 2, 3, 4, 5, 6, 7],
[ 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25]])
- 数组与数值相乘
In [14]: a*2
Out[14]:
array([[ 0, 2, 4, 6, 8, 10],
[12, 14, 16, 18, 20, 22],
[24, 26, 28, 30, 32, 34],
[36, 38, 40, 42, 44, 46]])
- 数组与数值相除
In [15]: a/2
Out[15]:
array([[ 0. , 0.5, 1. , 1.5, 2. , 2.5],
[ 3. , 3.5, 4. , 4.5, 5. , 5.5],
[ 6. , 6.5, 7. , 7.5, 8. , 8.5],
[ 9. , 9.5, 10. , 10.5, 11. , 11.5]])
广播原则:如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行.
如 shape为(3, 3, 3)的数组不能和(3, 2)的数组进行计算;shape为(3, 3, 2)的数组能和(3, 2)的数组进行计算;shape为(3, 3, 2)的数组能和(1, 2)的数组进行计算
与数组进行运算
数组与数组的运算:数组之间对应位置元素执行运算。
In [20]: b = np.arange(100,124).reshape((4,6))
In [21]: b
Out[21]:
array([[100, 101, 102, 103, 104, 105],
[106, 107, 108, 109, 110, 111],
[112, 113, 114, 115, 116, 117],
[118, 119, 120, 121, 122, 123]])
In [2]: c = np.arange(0,6)
In [3]: c
Out[3]: array([0, 1, 2, 3, 4, 5])
In [6]: d = np.arange(4).reshape((4,1))
In [7]: d
Out[7]:
array([[0],
[1],
[2],
[3]])
- 数组与数组相加
# 二维数组与同形状的二维数组相加
In [22]: a+b
Out[22]:
array([[100, 102, 104, 106, 108, 110],
[112, 114, 116, 118, 120, 122],
[124, 126, 128, 130, 132, 134],
[136, 138, 140, 142, 144, 146]])
# 二维数组与同列数的一维数组相加
In [4]: a+c
Out[4]:
array([[ 0, 2, 4, 6, 8, 10],
[ 6, 8, 10, 12, 14, 16],
[12, 14, 16, 18, 20, 22],
[18, 20, 22, 24, 26, 28]])
# 二维数组与同行数的二维数组相加
In [8]: a+d
Out[8]:
array([[ 0, 1, 2, 3, 4, 5],
[ 7, 8, 9, 10, 11, 12],
[14, 15, 16, 17, 18, 19],
[21, 22, 23, 24, 25, 26]])
- 数组与数组相乘
In [23]: a*b
Out[23]:
array([[ 0, 101, 204, 309, 416, 525],
[ 636, 749, 864, 981, 1100, 1221],
[1344, 1469, 1596, 1725, 1856, 1989],
[2124, 2261, 2400, 2541, 2684, 2829]])
numpy读取数据
np.loadtxt(frame,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)
参数 | 解释 |
---|---|
frame | 文件、字符串或产生器,可以是.gz或bz2压缩文件 |
dtype | 数据类型,可选,csv的字符串以什么数据类型读入数组中,默认 np.float |
delimiter | 分割字符串,默认是任何空格,改为 逗号 |
skiprows | 跳过前x行,一般跳过第一行表头 |
usecols | 读取指定的列,索引,元组类型 |
unpack | 如果True,读入属性将分别写入不同数组变量,False读入数据只写入一个数组变量,默认False(简单理解为数据的转置) |
使用此方法时,注意添加delimiter、dtype以及unpack的效果。因为不指定delimiter会导致每行数据为一个整体字符串而报错;不指定dtype默认情况下对于较大的数据会将变为科学计数的方式
numpy中的转置
转置是一种变换,对于numpy中的数组来说,就是在对角线方向交换数据,目的也是为了更方便处理数据。
In [9]: t = np.arange(18).reshape((3,6))
In [10]: t
Out[10]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17]])
- t.transpose()
- t.swapaxes(1,0)
- t.T
以上的三种方法都可以实现二维数组的转置。结果如下所示:
array([[ 0, 6, 12],
[ 1, 7, 13],
[ 2, 8, 14],
[ 3, 9, 15],
[ 4, 10, 16],
[ 5, 11, 17]])
numpy索引和切片
In [15]: a = np.arange(12).reshape((3,4))
In [16]:a
Out[16]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# 取一行
In [17]: a[1]
Out[17]: array([4, 5, 6, 7])
# 取一列
In [18]: a[:,2]
Out[18]: array([ 2, 6, 10])
# 取多行
In [19]: a[1:3]
Out[19]:
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# 取多列
In [20]: a[:,2:4]
Out[20]:
array([[ 2, 3],
[ 6, 7],
[10, 11]])
numpy中数值的修改
对a中的元素,重新赋值。将a的第3~5列的元素赋值为0
In [2]: a = np.arange(24).reshape((4,6))
In [3]: a[:,2:4]
Out[3]:
array([[ 2, 3],
[ 8, 9],
[14, 15],
[20, 21]])
In [4]: a[:,2:4] = 0
In [5]: a
Out[5]:
array([[ 0, 1, 0, 0, 4, 5],
[ 6, 7, 0, 0, 10, 11],
[12, 13, 0, 0, 16, 17],
[18, 19, 0, 0, 22, 23]])
numpy中布尔索引
# 将a小于10的元素赋值为3
In [6]: a[a<10]=3
In [7]: a
Out[7]:
array([[ 3, 3, 3, 3, 3, 3],
[ 3, 3, 3, 3, 10, 11],
[12, 13, 3, 3, 16, 17],
[18, 19, 3, 3, 22, 23]])
numpy中三元运算符
np.where()方法:将a小于10的元素赋值为0,大于10的元素赋值为10
In [8]: np.where(a<10,0,10)
Out[8]:
array([[ 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 10, 10],
[10, 10, 0, 0, 10, 10],
[10, 10, 0, 0, 10, 10]])
numpy中clip(裁剪)
此方法对于nan不会替换。
将a小于10的元素赋值为0,大于18的元素赋值为18。
In [9]: a
Out[9]:
array([[ 3, 3, 3, 3, 3, 3],
[ 3, 3, 3, 3, 10, 11],
[12, 13, 3, 3, 16, 17],
[18, 19, 3, 3, 22, 23]])
In [10]: a = a.astype(float)
In [11]: a[3,3]=np.nan
In [12]: a
Out[12]:
array([[ 3., 3., 3., 3., 3., 3.],
[ 3., 3., 3., 3., 10., 11.],
[12., 13., 3., 3., 16., 17.],
[18., 19., 3., nan, 22., 23.]])
In [13]: a.clip(10,18)
Out[13]:
array([[10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 11.],
[12., 13., 10., 10., 16., 17.],
[18., 18., 10., nan, 18., 18.]])
numpy中的nan和inf
-
nan与inf均为float类型
-
nan(NAN,Nan) : not a number 表示不是一个数字
(1) 什么时候numpy中会出现nan?
当读取本地文件为float的时候,如果有缺失,就会出现nan
当做了一个不合适的计算的时候(无穷大(inf)减去无穷大)
(2)统计数组中nan的个数
np.count_nonzero()方法统计数组中非0个数,由于两个nan是不相等的,通过 np.count_nonzero(t != t)可统计整个数组的nan个数。
(3)判断一个数字是否为nan:通过np.isnan(t)来判断,返回bool类型。效果等同于t != t -
inf(-inf,inf) : inf表示正无穷,-inf表示负无穷
(1) 什么时候会出现inf(包括-inf和inf)?
比如一个数字除以0(python中直接报错,numpy中是一个inf或-inf)
numpy数组的简单求和
In [14]: a
Out[14]:
array([[ 3., 3., 3., 3., 3., 3.],
[ 3., 3., 3., 3., 10., 11.],
[12., 13., 3., 3., 16., 17.],
[18., 19., 3., nan, 22., 23.]])
In [15]: np.sum(a)
Out[15]: nan
In [16]: np.sum(a,axis=0) # 等价于a.sum(,axis=0)
Out[16]: array([36., 38., 12., nan, 51., 54.])
In [17]: np.sum(a,axis=1) # 等价于a.sum(,axis=1)
Out[17]: array([18., 33., 64., nan])
numpy中常用统计函数
- 求和:t.sum(axis=None)
- 均值:t.mean(axis=None)
- 中值:np.median(t,axis=None)
- 最大值:t.max(axis=None)
- 最小值:t.min(axis=None)
- 极值:np.ptp(t,axis=None)
- 标准差:t.std(axis=None)
默认返回多维数组的全部统计结果,如果指定axis则返回当前轴上的结果
numpy中数组的拼接
In [8]: t1 = np.arange(12).reshape((2,-1))
In [9]: t1
Out[9]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
In [10]: t2 = np.arange(12,24).reshape((2,-1))
In [11]: t2
Out[11]:
array([[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
- 竖直拼接(vertically)
In [12]: np.vstack((t1,t2))
Out[12]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
- 水平拼接(horizontally)
In [13]: np.hstack((t1,t2))
Out[13]:
array([[ 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17],
[ 6, 7, 8, 9, 10, 11, 18, 19, 20, 21, 22, 23]])
numpy中其他方法
- 获取最大值最小值的位置
- np.argmax(t, axis=0)
- np.argmin(t,axis=1)
- 创建一个全0的数组:np.zeros((3,4))
- 创建一个全1的数组:np.ones((3,4))
- 创建一个对角线为1的正方形数组(方阵):np.eye(3)
numpy的random生成随机数
参数 | 解释 |
---|---|
.rand(d0,d1,…dn) | 创建d0-dn维度的均匀分布的随机数数组,浮点数,范围从0-1 |
.randn(d0,d1,…dn) | 创建d0-dn维度的标准正态分布随机数,浮点数,平均数0,标准差1 |
.randint(low,high,(shape)) | 从给定上下限范围选取随机数整数,范围是low,high, 形状是shape |
.uniform(low,high,(size)) | 产生具有均匀分布的数组,low起始值,high结束值,size形状 |
.normal(loc,scale,(size)) | 从指定正态分布中随机抽取样本,分布中心是loc(概率分布的均值),标准差是scale,形状是size |
.seed(s) | 随机树种子,s是给定的种子值。因为计算机生成的是伪随机数,所以通过设定相同的随机数中i,可以每次生成相同的随机数 |
numpy的注意点copy和view
- a = b完全不复制,a和b相互影响
- a = b[:],视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的。
- a = b.copy(),复制,a和b互不影响。