本文简单介绍了Python的基本概念、Numpy和SciPy的简单用法,非常适合初学者以及已经入门需要复习的Python学习者。文章来源于CS231n课程给予初学者的Python的初级教程,斯坦福大学的CS231n( Convolutional Neural Networks for Visual Recogniton),开课者是著名计算机视觉学者李飞飞教授。
目录
- Python
- 基本数据类型
- 容器(Containers)
- 列表(Lists)
- 字典(Dictionaries)
- 集合(Sets)
- 元组(Tuples)
- 函数(Functions)
- 类(Classes)
- Numpy
- 数组(Arrays)
- 数组索引(Array indexing)
- 数据类型
- Array math
- 广播(broadcasting)
- SciPy
- 图像处理(Image operations)
- 点之间的距离
- Matplotlib
- 作图(Plotting)
- 子图(Subplots)
- 图像(Images)
Python
Python是一种动态、多参数的高级编程语言。在Python里,用几行简单易读的代码就能让你天马行空的想法实现,所以有人说Python读起来就像是伪代码不无道理。
例如,在Python实现经典快排算法只需要这么几行
1 | def quicksort(arr): |
基本数据类型
与大多数编程语言类似,Python有许多数据类型,包括整数(integer)、浮点数(float)、布尔数(boolean)和字符串(string)。这些数据类型与其他编程语言的相比也没什么两样。
数字(Numbers):整数和浮点数的操作与其他编程语言的也没什么两样
1 | x = 3 |
注意,与其他编程语言不同,Python没有自增(++)和自减(—)的运算。
Python也还有为长整型和复杂数据准备的自建类型,你可以在这个文档链接中找到相关细节信息。
布尔型(Booleans):Python可以实现所有的布尔逻辑运算,不同于其他编程语言,它的运算符号都是英语单词,比如and
、or
、not
,而不是(&&
,||
)
1 | t = True |
字符串(Strings):
1 | hello = 'hello' # String literals can use single quotes(单引号或双引号都没关系) |
Python中的字符串还有一大堆好玩的玩法,比如
1 | s = "hello" |
你可以在这个链接中找到一些关于字符串的操作细节。
容器(Containers)
Python有几个自建容器类型:列表、字典、集合和元组。
列表(Lists)
Python中的列表等同于一个数组,然而列表可以改变大小,还可以容纳不同类型的元素,在Python中列表用[]
围起来
1 | xs = [3, 1, 2] # Create a list |
分片(Slicing):除了使用索引访问单个元素,Python还可以使用分片操作来访问某个范围内的元素
1 | nums = range(5) # range is a built-in function that creates a list of integers |
循环(Loops):针对列表中的元素,你也可以进行循环操作
1 | animals = ['cat', 'dog', 'monkey'] |
如果你想通过循环体来获得列表中元素的索引,还不如使用内建函数enumerate
1 | animals = ['cat', 'dog', 'monkey'] |
列表解析(List comprehensions):当使用Python编程的时候,经常我们需要将一类数据转换成另一种类型的数据。举一个简单的例子,看看下面这段计算平方的代码
1 | nums = [0, 1, 2, 3, 4] |
(是不是很简单?对在Python下面就是这么通俗易懂,所以说“人生苦短,我用Python”是不无道理的。)
你也可以通过列表解析让代码变得更简单
1 | nums = [0, 1, 2, 3, 4] |
列表解析在有条件限制的情形下也可以使用
1 | nums = [0, 1, 2, 3, 4] |
字典(Dictionaries)
Python中的字典数据类型存放键(key)、值(value),与Java中的map
和JavaScript中的对象(object)相似,在Python中你可以这样来使用它:
1 | d = {'cat': 'cute', 'dog': 'furry'} # Create a new dictionary with some data |
如果你想知道得更多关于字典的细节,访问文档链接
循环(Loops):在字典中遍历所有的键(keys)非常简单
1 | d = {'person': 2, 'cat': 4, 'spider': 8} |
如果你想获取字典中的键以及相应的值,使用iteritems
方法:
1 | d = {'person': 2, 'cat': 4, 'spider': 8} |
字典解析(Dictionary comprehensions):与列表解析相似,结构化字典也相当简单。比如
1 | nums = [0, 1, 2, 3, 4] |
集合(Sets)
在Python中,集合是由一组无序的各不相同的元素组成。举个简单例子,
1 | animals = {'cat', 'dog'} |
如果你想知道得更多关于集合的细节,访问文档链接
循环:集合中的循环语法与字典中的类似;然而因为集合是无序的,所以你无法知道集合中元素的顺序:
1 | animals = {'cat', 'dog', 'fish'} |
集合解析(Set comprehensions): 与列表和字典类似,我们可以通过Set comprehensions轻松构建集合
1 | from math import sqrt |
元组(Tuples)
元组与列表一样,也是一种序列,只不过,元组中的元素是不能被修改的。还有,在字典中元组可以作为键使用,在集合中当做元素,列表却不可以。比如
1 | d = {(x, x + 1): x for x in range(10)} # Create a dictionary with tuple keys, Prints "{(0, 1): 0, (1, 2): 1, (6, 7): 6, (5, 6): 5, (7, 8): 7, (8, 9): 8, (4, 5): 4, (2, 3): 2, (9, 10): 9, (3, 4): 3}" 是无序的 |
如果你想知道得更多关于元组的细节,访问文档链接。
函数(Functions)
在Python中函数通过def
来定义,比如,
1 | def sign(x): |
我们经常在定义函数时通常加上一些关键词声明(keywords augment),比如:
1 | def hello(name, loud=False): |
如果你想知道得更多关于函数的细节,访问文档链接。
类(Classes)
Python中定义类的语法非常直接
1 | class Greeter(object): |
如果你想知道得更多关于类的细节,访问文档链接
Numpy
Numpy是Python中负责科学计算的核心库之一。Numpy在处理多维数组上性能强大,它还有许多处理这些数组的工具。如果你事先熟悉了MATLAB,你可能发现会对你入门numpy有点点帮助。
数组(Arrays)
Numpy数组是相同类型的、有非负整数索引的、在网格状中的值。数据的维度等于数组的秩rank;数组的shape属性指的是数组的。。。。(说了这么多,按照我的理解,你就把Numpy中的数组看成是一个m*n的矩阵好了,shape属性是这个矩阵的行数和列数,索引的办法也是一层层的)
1 | import numpy as np |
Numpy也提供了许多建立(construct)数据的函数:
1 | import numpy as np |
通过这个文档链接获得更多关于创建数组的细节
数组索引(Array indexing)
Numpy提供几个索引数组的方法
分片:与Python的列表相似,Numpy也可以被分片。因为数组可能是多维度的,你必须明确数组中每个维度的分片
1 | import numpy as np |
你也可以将分片索引和整数索引混合使用。
1 | import numpy as np |
整数数组索引:当你使用切片索引Numpy数组时,结果永远是初始数组的一个子数组。相反,整数数组索引允许你使用数组中的数据重新建立绝对数组。比如:
1 | import numpy as np |
整数数组索引的一个有用技巧是选择或转换每一行的某一个元素
1 | import numpy as np |
布尔型数组索引:布尔型数组索引能够让你挑选出数组的绝对元素。通常,这种类型的索引被用于选择数组中满足某些条件的元素。比如
1 | import numpy as np |
如果你想了解跟过关于数组索引的细节,访问文档链接
数据类型
每个Numpy数组都是一组相同类型的数据。Numpy提供了许多数值类型,你可以用它们来建立数组。当你建立一个数组之后,Numpy就会尝试着猜测它的数据类型,函数就不一样,函数在创建数组的时候回特别声明它所处理数据的类型。比如
1 | import numpy as np |
关于Numpy数据类型的更多细节,访问文档链接。
Array math
基本的数学函数是可以适用数组的点乘的
1 | import numpy as np |
值得注意的是,不同于MATLAB,Numpy中的*
是点乘运算,而非矩阵乘法运算。所以我们用点dot
函数来计算向量的内积和进行矩阵和向量的乘法。点dot
同时也可以作为Numpy模块中的函数
1 | import numpy as np |
Numpy有很多计算数组的函数,其中一个便是sum
1 | import numpy as np |
你可以在这个文档链接找到Numpy中所有的数学函数
除了用数组来进行数学函数计算之外,我们通常需要重塑或者对数组进行其他操作。矩阵的转置是一个最简单的例子,简单的用T
就可以实现
1 | import numpy as np |
对于数组处理,Numpy提供了许多函数,在这个文档找到更多细节。
广播(broadcasting)
广播是Python中很强大的一种机制,在进行算术运算的时候,它能够允许Numpy对不同shape属性的数组进行操作。一般情况下, 我们会有一个较大的数组和一个较小的数组,也就是数组的shape属性不同,而我们想通过多次使用较小的数组来对较大的数组进行算术运算。
比如,假设我们需要给矩阵的每一行元素加上一个常数向量
1 | import numpy as np |
这样做的确可行,但是当矩阵x
非常大的时候,在Python中计算这样的循环任务将会非常缓慢。因为给矩阵x
的每一行加上一个v
等同于直接在矩阵上叠加vv
,然后对x
和叠加的矩阵vv
进行点对点的相加。如下
1 | import numpy as np |
Numpy的广播操作则允许我们无需创建v
的拷贝版本而直接进行计算。使用广播的话就简单很多了,广播通常也能够使你的代码更准确更迅速,换句话说,Python的广播机制使得运算更加方便
1 | import numpy as np |
是不是简化了许多!
对两个数组进行广播操作要遵循以下几个规则:
如果数组没有相同的秩(rank),那么将低秩数数组的shape属性加1,使得它们的shape属性一样;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import numpy as np
0, 60, 10).reshape(-1, 1) a = np.arange(
a
array([[ 0], [10], [20], [30], [40], [50]])
a.shape
(6, 1)
0, 5) b = np.arange(
b
array([0, 1, 2, 3, 4])
b.shape
(5,) # a与b的shape属性不同
c = a + b
c
array([[ 0, 1, 2, 3, 4],
[10, 11, 12, 13, 14],
[20, 21, 22, 23, 24],
[30, 31, 32, 33, 34],
[40, 41, 42, 43, 44],
[50, 51, 52, 53, 54]])
c.shape
(6, 5)
#二维数组a,其shape为(6,1),一维数组b,其shape为(5,),由于a和b的shape长度不同,根据规则1,需要让b的shape向a对齐,于是将b的shape前面加1,补齐为(1,5)广播之后,输出数组的shape是输入数组shape的各个轴上的最大值;
|A (4d array)|8 x 1 x 6 x 1|
|:—|—:|
|B (3d array)| 7 x 1 x 5|
|Result (4d array)|8 x 7 x 6 x 5|在任何维度,一个数组的大小为1而另一个数组的大小比1大,那么第一个数组。
1 | import numpy as np |
其实这个地方我也没弄太明白,我觉得应该类似于矩阵里边的运算,两个矩阵进行运算,第一个矩阵的列数必须跟第二个矩阵的行数相等,不然无法运算。Python的广播机制应该跟这个意思差不太多,只不过它帮你省去了思考的时间,但是自己在使用数组运算的时候应该事先就要考虑好矩阵的维度,不然会得出截然不同的结果。
后面我会继续跟进这个话题。
SciPy
SciPy提供大量用于计算Numpy数组的函数,并且对于不同行业的科学和工程有广泛的应用
图像处理(Image operations)
对于图像处理,SciPy有几个基本的处理函数。比如,从磁盘中读取图像并存放在Numpy数组中,可以在磁盘中写入Numpy数组存储为图像,可以重新调整图像大小。(图片本来由一个个的像素点组成,这些像素点即是组成数组的元素)下面是一个简单的例子
1 | from scipy.misc import imread, imsave, imresize |
点之间的距离
给定一个集合,函数scipy.spatial.distance.pdist
可以计算所有点之间的距离
1 | import numpy as np |
scipy.spatial.distance.cdist
是一个相似的函数,computes the distance between all pairs across two sets of points
Matplotlib
Matplotlib是一个专门用来作图的库。这小节中会对matplotlib.pyplot
函数简单介绍
作图(Plotting)
Matplotlib中最重要的一个函数是plot
,它可用来处理二维数据。
1 | import numpy as np |
运行代码,得到如下图形
再添加一点点额外代码就可以轻松同时画出多条曲线、添加标题、图例、轴标签
1 | import numpy as np |
子图(Subplots)
你也可以使用subplot
在同一张图片中画出不同的图像,下面是一个简单的例子,同时在一幅图中画出sin
和cos
的曲线
1 | import numpy as np |
图像(Images)
使用imshow
函数呈现图像
1 | import numpy as np |