python版本
python目前的版本分为2.7和3.5,两种版本的代码目前无法兼容,查看python版本号:
python --version
基本数据类型
数字类型
整型和浮点型数据和其它编程语言的用法基本一致:
x = 3 print(type(x)) print(x) print(x + 1) print(x - 1) print(x * 2) print(x ** 2) x += 1 print(x) x *=2 print(x) y = 2.5 print(type(y)) print(y,y + 1,y * 2,y ** 2) m = 5 n = 3 print(5 / 3) #精确除法,保留小数部分 print(5 // 3) #只取除法结果的整数部分 print(5 % 3) #两个整数相除取余 print(divmod(m,n)) #返回(x//y , x%y) print(pow(m,n)) #幂计算 a = -3 print(abs(a)) #绝对值计算 print(-a) #取反 print(+a) c = 2 -3j #复数 print(type(c)) print(c.real) #实部 print(c.imag) #虚部
结果:
<class 'int'> 3 4 2 6 9 4 8 <class 'float'> 2.5 3.5 5.0 6.25 1.6666666666666667 1 2 (1, 2) 125 3 3 -3 <class 'complex'> 2.0 -3.0
注意,与其它语言不同的一点是,python中没有自加、自减操作,即没有下面的运算:
i++ i--
bool类型
boo逻辑不是使用(&&,||,etc)而直接使用英语表示:
t = True f = False print(type(t)) print(t and f ) print(t or f) print(not f) print(t != f)
结果:
<class 'bool'> False True True True
string类型
hello = 'hello' world = "world" print(type(str(1))) #其它类型转换成字符串 print(hello) print(len(hello)) hw = hello + ' ' + world #字符串拼接 print(hw) print(3*hello) #复制字符串 print(2*'hi') hw12 = '%s %s %d' % (hello,world,12) #格式化输出 print(hw12) print('''line1 line2 line3''') #多行输出
结果:
<class 'str'> hello 5 hello world hellohellohello hihi hello world 12 line1 line2 line3
字符串的操作:
s = 'hello' print(s.capitalize()) #大写字符串首字母 print(s.upper()) #把字符串中的所有字母都变成大写 print(s) #字符串本身并没有变 S = 'HELLO' #把字符串中的所有字母都变成小写 print(S.lower()) #把字符串中的所有字母都变成大写 print(s.rjust(7)) #字符串长度变成7,左边补充空格占位 print(s.center(7)) #字符串长度变成7,左边右边各补充空格占位,字符串在中间 print(s.replace('l','(ell)')) #指定字符替换 print(' world '.strip()) ##去掉开头和结尾的空格
结果:
Hello HELLO hello hello hello hello he(ell)(ell)o world
Containers
python中内建的container类型有:lists,dictionaries,sets,tuples。
lists
python中的list就像是一个数组,但是其大小可变,并且list中的元素类型可以不一致。
xs = [3,1,2] print(xs,xs[2]) #按照索引获取list中的元素,索引值从0开始 print(xs[-1]) #负数索引反向获取list中的元素 xs[2] = 'foo' #修改list元素的值 print(xs) xs.append('bar') #在list末尾添加元素 print(xs) x = xs.pop() #弹出list末尾元素 print(x,xs)
结果:
[0, 1, 2, 3, 4] 2 4 [0, 1, 'foo', 3, 4] [0, 1, 'foo', 3, 4, 'bar'] bar [0, 1, 'foo', 3, 4]
list slice
list的slice形式获取元素:
nums = list(range(5)) print(nums) print(nums[2:4]) print(nums[2:]) print(nums[:2]) print(nums[:]) #list中的全部元素 print(nums[:-1]) #list除了最后的一个元素外的所有元素 nums[2:4] = [8 ,9] print(nums)
结果:
[0, 1, 2, 3, 4] [2, 3] [2, 3, 4] [0, 1] [0, 1, 2, 3, 4] [0, 1, 2, 3] [0, 1, 8, 9, 4]
注意slice方式获取list中的元素时,区间是左闭右开的形式。
list元素遍历
可以对list中的元素遍历获取:
animals = ['cat','dog','monky'] for animal in animals: print(animal)
结果:
cat dog monky
想获取元素的索引值可以使用内建函数enumerate
animals = ['cat','dog','monky'] for idx,animal in enumerate(animals): print('#%d: %s '% (idx+1,animal))
结果:
#1: cat #2: dog #3: monky
list comprehensions
普通的方法实现:
nums = [, , , , ] squares = [] for x in nums: squares.append(x ** ) print(squares)
list comprehension 方法实现:
nums = [0, 1, 2, 3, 4] squares = [x**2 for x in nums] print(squares)
结果:
[0, 1, 4, 9, 16]
list comprehension中也可以有if条件表达式:
nums = [0, 1, 2, 3, 4] squares = [x**2 for x in nums if x % 2 ==0] print(squares)
结果:
[0, 4, 16]
Dictionaries
字典是一种键-值组合:
d = {'cat':'cute','dog':'furry'} print(d['cat']) #按照键来索引值 print('cat' in d) #判断字典中是否存在某个元素 d['fish'] = 'wet' #向字典中增加一个元素 print(d['fish']) print(d.get('monky','N/A')) #使用默认值返回索引字典中的元素,如果字典中没有这个元素按照默认值返回 print(d.get('fish','N/A')) del d['fish'] print(d.get('fish','N/A'))
结果:
cute True wet N/A wet N/A
Dictionaries 元素遍历
d = {'person':2,'cat':4,'spider':8} for animal in d: legs = d[animal] print('A %s has %d legs' % (animal,legs))
结果:
A cat has 4 legs A person has 2 legs A spider has 8 legs
使用items()可以同时遍历键-值:
d = {'person':2,'cat':4,'spider':8} for animal,legs in d.items(): print('A %s has %d legs' % (animal,legs))
结果:
A spider has 8 legs A person has 2 legs A cat has 4 legs
Dictionary comprehensions
使用这种方法能够快速的创建一个Dictionary :
nums = [0,1,2,3,4] even_num_to_square = {x:x**2 for x in nums if x % 2 == 0} print(even_num_to_square)
结果:
{0: 0, 2: 4, 4: 16}
Sets
Sets是一个无序的不同元素的集合:
animals = {'cat','dog'} print('cat' in animals) #判断元素是否在集合中 print('fish' in animals) animals.add('fish') #集合中添加元素 print('fish' in animals) print(len(animals)) #集合中元素的个数 animals.add('cat') #集合中元素互异,相同的元素继续添加无效 print(len(animals)) animals.remove('cat') #删除集合中某个元素 print(len(animals))
结果:
True False True 3 3 2
遍历sets中的元素
因为sets中的元素顺序是不固定的,所以没办法确定每次要访问的元素究竟是哪个:
animals = {'cat','dog','fish'} for idx,animal in enumerate(animals): print('#%d: %s' % (idx + 1,animal))
运行上面的代码,每次输出的结果可能是不一样的:
#first time #1: fish #2: cat #3: dog #seconde time #1: cat #2: fish #3: dog
sets comprehensions
from math import sqrt nums = {int(sqrt(x)) for x in range(30)} print(nums)
结果:
{0, 1, 2, 3, 4, 5}
tuples
tuples是一个不可变的有序列表。tuples和list是十分相似的,但是tuple可以作为dictionaries中的key以及set中的元素,而list不可以。
d = {(x,x+1):x for x in range(10)} t = (5,6) print(type(t)) print(d[t]) print(d[(1,2)])
结果:
<class 'tuple'> 5 1
函数
python中使用def定义函数:
def sign(x): if x > 0: return 'positive' elif x < 0: return 'negative' else: return 'zero' for x in [-1,0,1]: print(sign(x))
结果:
negative zero positive
默认参数函数:
def hello(name,loud = False): if loud: print("Hello,%s!" % name.upper()) else: print("Hello,%s!" % name) hello('Bob') hello('Fred',loud = True)
结果:
Hello,Bob! Hello,FRED!
class
python中类定义
class Greeter(object): #构造函数 def __init__(self,name): self.name = name #成员函数 def greet(self, loud = False): if loud: print("Hello,%s!" % self.name.upper()) else: print("Hello,%s!" % self.name) g = Greeter('Fred') g.greet() g.greet(loud = True)
结果:
Hello,Fred! Hello,FRED!
Numpy
numpy是python中的科学计算库,它提供了高性能多维度矩阵计算的方法:
Arrays
array是一种网格数据类型,使用非负整数来索引,矩阵的维度称为rank,矩阵的shape是一个tuple类型用来给出每个维度的大小。
一维:
import numpy as np a = np.array([1,2,3]) print(type(a)) print(a.shape) print(a[0],a[1],a[2]) a[0] = 5 print(a)
结果:
<class 'numpy.ndarray'> (3,) 1 2 3 [5 2 3]
二维:
import numpy as np b = np.array([[1,2,3],[4,5,6]]) print(b.shape) print(b[0,0],b[0,1],b[1,0])
结果:
(2, 3) 1 2 4
创建array的方法:
import numpy as np a = np.zeros((2,2)) #创建元素都为0的矩阵 print(a) b = np.ones((1,2)) #创建元素都是1的矩阵 print(b) c = np.full((2,2),7) #创建指定常数矩阵 print(c) d =np.eye(2) #创建单位矩阵 print(d) e = np.random.random((2,2)) #创建0-1之间的随机数矩阵 print(e)
结果:
[[ 0. 0.] [ 0. 0.]] [[ 1. 1.]] [[ 7. 7.] [ 7. 7.]] [[ 1. 0.] [ 0. 1.]] [[ 0.4807756 0.15706773] [ 0.4037694 0.36633278]]
Array indexing
跟list一样,array也可以使用slice方法,但是因为array是多维的,所以使用时必须指定array的相应维度:
import numpy as np a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]]) b = a[:2,1:3] #前两行,1-2列 print(b) b[0,0] = 88 #在slice中改变数据会影响原矩阵中的数据 print(a[0,1])
结果:
[[2 3] [6 7]] 88
注意以下两种方式获取的矩阵维度是不同的,仅用数字获得的是低阶的,使用slice能够获得与原矩阵相同维度的矩阵:
import numpy as np a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]]) row_r1 = a[1,:] #第2行所有元素 row_r2 = a[1:2,:] #第2行所有元素 print(row_r1,row_r1.shape) print(row_r2,row_r2.shape)
结果:
[5 6 7 8] (4,) [[5 6 7 8]] (1, 4)
取列:
import numpy as np a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]]) col_r1 = a[:, 1] #第2行所有元素 col_r2 = a[:, 1:2] #第2行所有元素 print(col_r1,col_r1.shape) print(col_r2,col_r2.shape)
结果:
[ 2 6 10] (3,) [[ 2] [ 6] [10]] (3, 1)
使用整数索引而非slice索引能够让你构建任意维度的矩阵:
import numpy as np a = np.array([[1,2], [3, 4], [5, 6]]) print(a[[0, 1, 2], [0, 1, 0]])
结果:
[1 4 5]
使用整数索引也可以重复使用原始矩阵中的元素
import numpy as np a = np.array([[1,2], [3, 4], [5, 6]]) print(a[[0, 0], [1, 1]])
结果:
[2 2]
上面的操作等同于:
import numpy as np a = np.array([[1,2], [3, 4], [5, 6]]) print(np.array([a[0, 1], a[0, 1]]))
结果:
[2 2]
获取矩阵中的每行指定位置的元素
import numpy as np #创建一个原始矩阵 a = np.array([[1,2,3], [4,5,6], [7,8,9],[10,11,12]]) print(a) #创建一个索引矩阵 b = np.array([0,2,0,1]) print(b) #使用索引每行选取一个值 print(a[np.arange(4),b]) #使用索引为每行中的指定元素增加一个值 a[np.arange(4),b] += 10 print(a)
结果:
[[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]] [0 2 0 1] [ 1 6 7 11] [[11 2 3] [ 4 5 16] [17 8 9] [10 21 12]]
Boolean 类型索引
Boolean 类型的索引能够从矩阵中挑选出满足指定条件的任意元素:
import numpy as np #创建一个原始矩阵 a = np.array([[1,2], [3,4], [5,6]]) print(a) #打印出的矩阵维度与原矩阵相同 bool_idx = (a > 2) print(bool_idx) #打印出满足一定条件的矩阵元素 print(a[a>2])
结果:
[[1 2] [3 4] [5 6]] [[False False] [ True True] [ True True]] [3 4 5 6]
数据类型
numpy中创建矩阵时有默认的数据类型,但是实际使用时也可以明确指出数据类型:
import numpy as np x = np.array([1,2]) print(x.dtype) x = np.array([1.0,2.0]) print(x.dtype) x = np.array([1,2],dtype = np.int64) print(x.dtype)
结果:
int32 float64 int64
Array math
elementwise
矩阵元素一般是elementwise:
import numpy as np x = np.array([[1,2],[3,4]], dtype=np.float64) y = np.array([[5,6],[7,8]], dtype=np.float64) print(x + y) print(np.add(x, y)) print(x - y) print(np.subtract(x, y)) print(x * y) print(np.multiply(x, y)) print(x / y) print(np.divide(x, y))
结果:
[[ 6. 8.] [ 10. 12.]] [[ 6. 8.] [ 10. 12.]] [[-4. -4.] [-4. -4.]] [[-4. -4.] [-4. -4.]] [[ 5. 12.] [ 21. 32.]] [[ 5. 12.] [ 21. 32.]] [[ 0.2 0.33333333] [ 0.42857143 0.5 ]] [[ 0.2 0.33333333] [ 0.42857143 0.5 ]]
dot
需要注意的是*表示矩阵元素对应相乘即elementwise,若要使用矩阵相乘,需要使用dot:
import numpy as np x = np.array([[1,2],[3,4]], dtype=np.float64) y = np.array([[5,6],[7,8]], dtype=np.float64) v = np.array([9,10]) w = np.array([11,12]) print(v.dot(w)) print(np.dot(v, w)) print(x.dot(v)) print(np.dot(x, v)) print(x.dot(y)) print(np.dot(x, y))
结果:
219 219 [ 29. 67.] [ 29. 67.] [[ 19. 22.] [ 43. 50.]] [[ 19. 22.] [ 43. 50.]]
sum
import numpy as np x = np.array([[1,2],[3,4]], dtype=np.float64) #所有元素求和 print(np.sum(x)) #列求和 print(np.sum(x, axis = 0)) #行求和 print(np.sum(x, axis = 1))
矩阵转置
import numpy as np #二维矩阵转置 x = np.array([[1,2],[3,4]], dtype=np.float64) print(x) print(x.T) #一维矩阵转置没有任何变化 v = np.array([1,2,3]) print(v) print(v.T)
结果:
[[ 1. 2.] [ 3. 4.]] [[ 1. 3.] [ 2. 4.]] [1 2 3] [1 2 3]
Broadcasting
Broadcasting 是numpy中一种强大的机制,它允许使用不同维度的矩阵之间进行数学计算,通常我们会有一个小矩阵和一个大的矩阵,为了实现计算我们会将小矩阵使用多次:
import numpy as np x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]]) v = np.array([1, 0, 1]) #创建一个与x维度相同的空矩阵 y = np.empty_like(x) for i in range(4): y[i, :] = x[i,:] + v print(y)
结果:
[[ 2 2 4] [ 5 5 7] [ 8 8 10] [11 11 13]]
上面的操作显示的使用for循环,这在python中的执行是十分缓慢的,我们的想法是,创建一个和x维度相同的矩阵,然后elementwise操作:
import numpy as np x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]]) v = np.array([1, 0, 1]) #获得v的四份拷贝 vv = np.tile(v, (4, 1)) print(vv) y = x + vv print(y)
结果:
[[1 0 1] [1 0 1] [1 0 1] [1 0 1]] [[ 2 2 4] [ 5 5 7] [ 8 8 10] [11 11 13]]
numpy中的broadcasting机制使得我们不要创建v的多份拷贝,而直接执行加法:
import numpy as np x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]]) v = np.array([1, 0, 1]) y = x + v print(y)
结果:
[[ 2 2 4] [ 5 5 7] [ 8 8 10] [11 11 13]]
其它例子:
import numpy as np v = np.array([1,2,3]) w = np.array([4,5]) #outer product print(np.reshape(v, (3, 1)) * w) #v broadcast to 2*3 x = np.array([[1,2,3], [4,5,6]]) print(x + v) #w broadcast to 3*2 然后和x.T相加 print((x.T + w).T) #wbroadcast to 2*3 然后和x相加 print(x + np.reshape(w, (2, 1)))
结果:
[[ 4 5] [ 8 10] [12 15]] [[2 4 6] [5 7 9]] [[ 5 6 7] [ 9 10 11]] [[ 5 6 7] [ 9 10 11]]
SciPy
SciPy 提供了大量基于numpy矩阵的计算,适用于各种科学和工程应用:
Image operations
SciPy 中提供了图像的相关的基本操作:
from scipy.misc import imread,imsave,imresize img = imread('./dog.jpg') print(img.dtype,img.shape) #R通道数据保持不变,G通道*0.95,B通道*0.7 im_tinted = img * [1, 0.95, 0.7] img_tinted = imresize(im_tinted, (300, 300)) imsave('./dog_tinted.jpg', img_tinted)
Matplotlib
Matplotlib 是一个绘制库。
Plotting
import numpy as np import matplotlib.pyplot as plt x = np.arange(0, 3 * np.pi, 0.1) y = np.sin(x) plt.plot(x, y) plt.show() # You must call plt.show() to make graphics appear.
import numpy as np import matplotlib.pyplot as plt x = np.arange(0,3*np.pi,0.1) y_sin = np.sin(x) y_cos = np.cos(x) plt.plot(x,y_sin) plt.plot(x,y_cos) plt.xlabel('x asix label') plt.ylabel('y asix label') plt.title('Sine and Consine') plt.legend(['Sine', 'Cosine']) plt.show()
Subplots
import numpy as np import matplotlib.pyplot as plt x = np.arange(0,3*np.pi,0.1) y_sin = np.sin(x) y_cos = np.cos(x) plt.subplot(2,1,1) plt.plot(x,y_sin) plt.title('Sine') plt.subplot(2,1,2) plt.plot(x,y_cos) plt.title('Consine') plt.show()
Images
import numpy as np from scipy.misc import imread, imresize import matplotlib.pyplot as plt img = imread('./dog.jpg') img_tinted = img * [1, 0.95, 0.9] plt.subplot(1, 2, 1) plt.imshow(img) plt.subplot(1, 2, 2) plt.imshow(np.uint8(img_tinted)) plt.show()