Python学习(二)Numpy学习

参考资料:

https://github.com/lijin-THU/notes-python(相应实体书为:《自学Python——编程基础、科学计算及数据分析》)

https://www.jianshu.com/p/57e3c0a92f3a (NumPy Tutorial - TutorialsPoint教程)

Numpy学习

import numpy as np 或 from numpy import *  //在ipython中可以使用 %pylab 快速导入numpy和matplotlib

一、数组array  //数组可以进行数学操作,对应元素进行+、-、*(非矩阵乘法)、/等

a = [1, 2, 3, 4]; a = np.array(a);   //列表转化为数组,等价于a = array([1, 2, 3, 4])

1. 基本属性

  • type(a)  //查看数组类型:numpy.ndarray
  • a.dtype  //查看数组中的数据类型,如dtype('int32')
  • a.itemsize  //查看数组中每个元素占的字节数,如4;查看数组所有元素所占空间用a.nbytes
  • a.shape  //查看数组形状,返回元组,如(4,)代表一个秩为1的数组;或者 shape(a)  shape()也可以作用于列表类型
  • a.size  //查看元素数目,或者size(a)
  • a.ndim  //查看数组维数
  • a.fill(-4.8)  //使用 fill 方法将数组设定为指定值;数组要求元素类型与dtype一致,不一致时会进行类型转换,此处结果为 array([-4, -4, -4, -4])

2. 索引和切片

(1)数组的基本切片在内存中使用的是引用机制(基本切片返回视图)

1 a = array([0,1,2,3,4])
2 b = a[2:4]  #python并没有为b分配新的空间来存储它的值,而是让b指向了a所分配的内存空间
3 b[0] = 10  #因此,改变b会改变a的值;此时a为array([ 0,  1, 10,  3,  4])
#这种现象在列表中不会出现
a = [1,2,3,4,5]
b = a[2:3]
b[0] = 13234
print a  #a仍然为[1,2,3,4,5]
  • 优点:对于很大的数组,不用大量复制多余的值,节约空间
  • 缺点:出现改变一个值改变另一个值的情况
  • 解决方案:使用copy()方法,申请新内存产生一个复制,如b = a[2:4].copy()

(2)花式索引(常规切片只能支持连续或者等间隔的切片操作)——高级索引返回数据副本(新内存)

注:花式索引返回的是原对象的一个复制(新内存)而不是引用

  • 一维花式索引(位置或布尔数组
 1 a = arange(0, 80, 10)  #产生等差数组
 2 indices = [1, 2, -3]  #指定索引位置
 3 y = a[indices]
 4 
 5 mask = array([0,1,1,0,0,1,0,0], dtype=bool)  #生成布尔数组
 6 a[mask]
 7 
 8 from numpy.random import rand
 9 a = rand(10)
10 mask = a > 0.5  #用布尔表达式生成布尔数组mask
11 a[mask]
  • 二维花式索引(需要给定行row和列col的值)
1 a = array([[ 0, 1, 2, 3, 4, 5],
2            [10,11,12,13,14,15],
3            [20,21,22,23,24,25],
4            [30,31,32,33,34,35],
5            [40,41,42,43,44,45],
6            [50,51,52,53,54,55]])
7 a[(0,1,2,3,4), (1,2,3,4,5)]  #返回次对角线上的5个值
8 a[3:, [0,2,5]]  #返回最后三行的第1,3,5列
#使用mask进行索引
9 mask = array([1,0,1,0,0,1], dtype=bool)
10 a[mask, 2]
  •  where语句:where(array)  //返回所有非零元素的索引

3. 数组类型

(1)整数数组

(2)浮点数数组

(3)布尔数组

(4)复数数组:a = array([1 + 1j, 2, 3, 4])    

  • 数组类型a.dtype = dtype('complex128')
  • 实部:a.real  array([1.,  2.,  3.,  4.]) 
  • 虚部:a.imag  array([1.,  0.,  0.,  0.]) 
  • 复共轭:a.conj()

(5)指定/改变数组类型 a = array([0,1.0,2,3], dtype=float32)

Numpy类型

(6)asarray()函数:asarray不会修改原来数组的值,但当类型相同的时候,asarray并不会产生新的对象,而是使用同一个引用

1 a = array([1.5, -3],  dtype=float32)
2 asarray(a, dtype=float64)  #不修改原数组a
3 asarray(a, dtype=uint8)  #不修改原数组a
4 b = asarray(a, dtype=float32)
5 b is a  #True  使用同一个引用

优点:不仅可以作用于数组,还可以将其他类型转化为数组。例如,为了保证我们的输入值是数组,我们需要将其使用asarray进行转化,当输入已经是数组时,不会产生新的对象,保证了效率。

(7)astype()方法:返回一个新数组(新内存)  a.astype(float64)

注:astype也不改变原数组,但是总是返回原来数组的一份复制,即使转换的类型是相同的

(8)view()方法:共用一块内存

1 a = array((1,2,3,4), dtype=int32)
2 b = a.view(uint8)  #view会将 a 在内存中的表示看成是 uint8 进行解析
3 a[0] = 2**30  #a 和 b 共用一块内存,修改 a 会修改 b 的值

4. 数组常用方法 a = array([ [1,2,3],  [4,5,6] ])  //对于二维数组,列为第一维(axis=0),行为第二维(axis=1)

(1)求和:sum(a, axis=维度)或者 a.sum(axis=维度) 不指定维度则对所有元素求和 //函数形式、方法形式

(2)求积:prod(a, axis=维度)或者 a.prod(axis=维度)  不指定维度则对所有元素求和 //函数形式、方法形式

(3)求最大最小值及其相应位置min()、max()、argmin()、argmax()

1 from numpy.random import rand
2 a = rand(3, 4)
3 a.min()  #全局最小
4 a.min(axis=0)  #沿某个轴最小
5 a.argmin()  #全局最小值位置
6 a.argmin(axis=0)  #沿某个轴最小值位置

(4)均值mean()、average()

1 a = array([[1,2,3],[4,5,6]])
2 a.mean()  #全局平均  "方法"
3 a.mean(axis=-1)  #沿某轴平均
4 mean(a)  #mean函数
5 average(a, axis = 0)  #average函数
6 average(a, axis = 0, weights=[1,2])  #加权平均

(5)标准差、方差std()、var()

1 a.std(axis=1)  #方法
2 a.var(axis=1)
3 std(a, axis=1)  #函数
4 var(a, axis=1)

(6)将数值限制在某个范围 clip(),如 a.clip(3,5)  //将小于3的变成3,大于5的变成5

(7)计算最大值和最小值之差 ptp(),如a.ptp()、a.ptp(axis=1)

(8)近似方法 round()

1 a = array([1.35, 2.5, 1.5])
2 a.round()  #.5的近似规则为近似到偶数值
3 a.round(decimals=1)  #近似到一位小数

5. 数组排序

sort()函数:返回从小到大排列的新数组不改变原数组

sort()方法:返回从小到大排列的数组,改变原数组;对于多维数组,sort方法默认沿着最后一维开始排序(如对于二维数组,默认对行进行排序)

argsort()函数、argsort()方法:返回从小到大的排列在数组中的索引位置,不改变原数组

1 %pylab
2 names = array(['bob', 'sue', 'jan', 'ad'])
3 weights = array([20.8, 93.2, 53.4, 61.8])
4 
5 sort(weights)
6 ordered_indices = argsort(weights)
7 weights[ordered_indices]
8 data.argsort()
9 data.sort()  #改变原数组 

 searchsorted(sorted_array, values)函数:接受两个参数,第一个必须是已排序的数组,第二个为查找的值,返回值为“保持第一个数组的排序性质不变,将第二个数组中的值插入第一个数组中的位置

1 from numpy.random import rand
2 data = rand(100)
3 data.sort()
4 bounds = .4, .6  #不加括号,默认是元组,等价于(0.4, 0.6)
5 low_idx, high_idx = searchsorted(data, bounds)  #返回这两个值对应的插入位置
6 data[low_idx:high_idx]  #利用插入位置,将数组中所有在这两个值之间的值提取出来

 6. 数组形状

(1)修改数组形状

1 %pylab
2 a = arange(6)
3 a.shape = 2,3  #修改原数组形状
4 a.reshape(3,2)  #返回修改后的新数组,不修改原数组

注:shape 和 reshape 方法不能改变数组中元素的总数,否则会报错

(2)增加数组维数:newaxis  //不修改原数组

1 a = arange(3)
2 shape(a)  #(3,)
3 y = a[newaxis, :]
4 shape(y)  #(3,1)
5 y = a[:, newaxis]
6 shape(y)  #(1,3)
7 y = a[newaxis, newaxis, :]  #增加多个维数
8 shape(y)  #(1,1,3)

(3)去除多余的轴:squeeze  //返回一个将所有长度为1的维度去除的新数组

1 a = arange(6)
2 a.shape = (2,1,3)
3 b = a.squeeze()
4 b.shape  #(2,3)

(4)数组转置:a.transpose()或者a.T  //对于复数数组,转置并不返回复共轭,只是单纯的交换轴的位置

#多维数组转置
1
a = arange(60) 2 a.shape = 3,4,5 3 b = a.T 4 b.shape  #(5,4,3)  转置只是交换了轴的位置

注:转置返回的是对原数组的另一种view,所以改变转置会改变原来数组的值

 (5)数组连接:concatenate((a0, a1, ..., aN), axis=0)  //除了给定的连接轴外,这些数组其他轴的长度必须一致

1 x = array([ [0,1,2], [10,11,12] ])  #x.shape=(2,3)
2 y = array([ [50,51,52], [60,61,62] ])  #y.shape=(2,3)
3 z = concatenate((x,y))  #默认沿着第一维进行连接,z.shape=(4,3);等价于 vstack((x, y)) 4 z = concatenate((x,y), axis=1)  #沿着第二维进行连接,z.shape=(2,6);等价于 hstack((x, y)) 5 z = array((x,y))  # x 和 y 的形状是一样的,可以将它们连接成三维的数组,z.shape=(2,2,3);等价于 dstack((x, y))

(6)将多维数组转化为1维数组:flatten()方法、flat属性、ravel()方法

 1 a = array([ [0,1], [2,3] ])
 2 b = a.flatten()  #b = array([0,1,2,3]),返回的是数组的复制,修改b并不会影响a
 3 
 4 b = a.flat  #a.flat 相当于返回了所有元组组成的一个迭代器,即b为numpy.
 5 print(b)  #b为numpy.flatiter,修改b会影响a
 6 a.flat[:]  #array([0,1,2,3])
 7 
 8 b = a.ravel()  #b为array([0,1,2,3]),但是修改b会影响a
 9 
10 a = array([ [0,1], [2,3] ])
11 aa = a.transpose()
12 b = aa.ravel()  #在这种情况下,修改b并不会改变aa和a的值,原因是我们用来ravel的对象 aa 本身是 a 的一个view

(7)保证数组至少有x维:atleast_xd()函数;x可以取值1,2,3

1 x = 1
2 atleast_1d(x)  #输出array([1])
3 a = array([1,2,3])  #(3,)
4 b = atleast_2d(a)  #b为array([[1,2,3]])
5 b.shape  #(1,3)
6 c = atleast_3d(b)  #c为array([[[1],[2],[3]]])
7 c.shape  #(1,3,1)

SciPy中用来保证输入满足一定条件的函数

 7. 查看对角线元素:diagonal()

 1 import numpy as np
 2 a = np.array([11,21,31,12,22,32,13,23,33])
 3 a.shape = 3,3
 4 a.diagonal()  #查看对角线元素
 5 #使用偏移查看次对角线
 6 a.diagonal(offset=1)  #正数表示右移
 7 a.diagonal(offset=-1)  #负数表示左移
 8 #花式索引对角线元素
 9 i = [0,1,2]
10 a[i, i]
11 a[i, i] = 2  #更新对角线值
12 #更新次对角线值
13 i = np.array([0,1])  #定义为数组,便于实现+1操作
14 a[i, i + 1] = 1
15 a[i + 1, i] = -1

8. 数组与字符串的转换,tostring()、fromstring()

1 import numpy as np
2 a = np.array([[1,2], [3,4]],  dtype = np.uint8)
3 a.tostring()  #转化为字符串,按照行进行转换
4 a.tostring(order='F')  #使用Fortran格式,按照列读取数据
5 s = a.tostring()  
6 a = np.fromstring(s, dtype=np.uint8)  #从字符串中读出数据,需要指定数据类型,返回一维数组
7 a.shape = 2,2  #重新设定数组维度
  • 对于文本文件,推荐使用:loadtxt、genfromtxt、savetxt
  • 对于二进制文件,推荐使用:save、load、savez

二、matplotlib

(可参考《python绘图工具基础-matplotlib学习之基本使用》——https://mp.weixin.qq.com/s/0gijX0Xn24tmui5pT1Zx9Q)

注:在脚本中使用 plot 时,通常图像是不会直接显示的,需要增加 show() 选项,只有在遇到 show() 命令之后,图像才会显示

 1 %matplotlib inline
 2 x = linspace(0, 2 * pi, 50)  #生成一组等间隔的数据
 3 plot(sin(x))  #默认以下标为x轴
 4 plot(x, sin(x))  #给定x轴
 5 plot(x, sin(x), x, sin(2 * x))  # 多条数据线;默认输入多次画图会自动叠加(不覆盖),如plot(x);plot(y); 
 # 可以跟Matlab类似用 hold(False) 关掉,这样新图覆盖旧图;hold(True)恢复原先设定
6 plot(x, sin(x), 'r-^')  # 指定线条参数 7 plot(x, sin(x), 'b-o', x, sin(2 * x), 'r-^') 8 plot(x, sin(x), 'bo')  # 散点图绘制方法一 9 scatter(x, sin(x))  # 散点图绘制方法二:scatter()函数 10 x = rand(200) 11 y = rand(200) 12 size = rand(200) * 30 13 color = rand(200) 14 scatter(x, y, size, color)  # 指定散点图大小、颜色参数 15 colorbar() # 显示颜色条 16 t = linspace(0, 2*pi, 50) 17 x = sin(t) 18 y = cos(t) 19 figure()  # 使用figure()命令产生新的图像,以绘制多图 20 plot(x) 21 figure() 22 plot(y) 23 subplot(1, 2, 1)  # 绘制单张图的子图,subplot(row, column, index) 24 plot(x) 25 subplot(1, 2, 2) 26 plot(y)
  • label参数添加标签:plot(x, label='sin')
  • legend()参数添加图例:legend()或者legend(['sin', 'cos']) 将标签和图例合并

1. 设置坐标轴标签和标题

1 plot(x, sin(x))
2 xlabel('radians')
3 # 可以设置字体大小
4 ylabel('amplitude', fontsize='large')
5 title('Sin(x)')
6 grid()  #显示网格
  • 清除、关闭图像:clf() 清除已有图像;close() 关闭当前图像;close('all') 关闭所有图像

2. imshow显示图像:

 1 from scipy.misc import ascent  #或者face图像,lena图像已被取消
 2 img = ascent()  #获取图像数据,或者face()
 3 img.shape
 4 imshow(img,
 5        # 设置坐标范围
 6       extent = [-250, 250, -250, 250],
 7        # 设置colormap
 8       cmap = cm.bone)  #cm表示colormap,可以用dir(cm)查看看它的种类
 9 colorbar()
10 imshow(img, cmap=cm.RdGy_r)  #使用不同的colormap会有不同的显示效果
  • 生成直方图:hist(randn(1000))  //利用高斯分布随机生成1000个点绘制直方图
posted @ 2019-01-18 10:04  从头再来,不要慌  阅读(953)  评论(0编辑  收藏  举报