|
本文主要根據(jù) 斯坦福CS231n課程的Python 教程進(jìn)行整理,原文地址為http://cs231n./python-numpy-tutorial/,官方Python指南網(wǎng)址https://www./doc/
Python是本身是一個(gè)通用的編程語(yǔ)言,但其具有一些庫(kù)(numpy,scipy,matplotlib)用于科學(xué)運(yùn)算,原文的Python的版本是3.5。
本文先進(jìn)行Python的基本介紹(數(shù)據(jù)、容器、函數(shù)、類)然后再介紹Numpy庫(kù)、SciPy庫(kù)以及MatPlotlib庫(kù)的常用方法。
Python基本數(shù)據(jù)類型
- 整型 int ,浮點(diǎn)型 float (注:Python沒(méi)有i++這種語(yǔ)句,乘方用x**i)
- 布爾型 booleans (注:Python 使用 and 、or、not替代C語(yǔ)言的&&、||、??;t!=f表示t和f的異或)
- 字符串型 strings (注:Python中字符串可以用單引號(hào)或雙引號(hào)表示,一些常用的函數(shù)如大小寫、去除空格、字符串替換、空格位置調(diào)整等,去掉空格s.strip()字符串替換s.replace('l','ell')具體使用什么函數(shù)可以現(xiàn)查)
Python容器
- 列表 list,與數(shù)組相同但是可變大?。ㄗⅲ合聵?biāo)從0開始算,與maltab從1開始算不同)
xs = [3, 1, 2] # Create a list print(xs, xs[2]) # Prints "[3, 1, 2] 2" 注意小標(biāo)從0開始 print(xs[-1]) # 負(fù)數(shù)下標(biāo)從后往前數(shù); prints "2" xs[2] = 'foo' # 列表的元素可以類型不同 print(xs) # Prints "[3, 1, 'foo']" print(xs) # Prints "[3, 1, 'foo', 'bar']" x = xs.pop() # 刪除最后一個(gè)元素 print(x, xs) # Prints "bar [3, 1, 'foo']"
切片:list使用中的一個(gè)重要方法(注:切片的下標(biāo)左邊界包含,右邊界不包含,與matlab兩邊界都包含不同)
nums = list(range(5)) # 利用list()函數(shù)生成列表 print(nums) # Prints "[0, 1, 2, 3, 4]" print(nums[2:4]) # 切片下標(biāo)2到(4-1); prints "[2, 3]" print(nums[2:]) # 切片下標(biāo)2到最后; prints "[2, 3, 4]" print(nums[:2]) # 切片開始到下標(biāo)(2-1); prints "[0, 1]" print(nums[:]) # 切片全部; prints "[0, 1, 2, 3, 4]" print(nums[:-1]) # 切片開始到(-1-1); prints "[0, 1, 2, 3]" nums[2:4] = [8, 9] # 將下標(biāo)2,3的值替換成8,9 print(nums) # Prints "[0, 1, 8, 9, 4]"
列表元素循環(huán)(與matlab相同)
animals = ['cat', 'dog', 'monkey']
也可以利用內(nèi)建函數(shù)enumerate(Lists)取得下標(biāo)(從0開始)和元素
animals = ['cat', 'dog', 'monkey'] for idx, animal in enumerate(animals): print('#%d: %s' % (idx + 1, animal)) # Prints "#1: cat", "#2: dog", "#3: monkey", each on its own line
列表解析:一種生成新的列表的方式,舉兩個(gè)例子
squares = [x ** 2 for x in nums] print(squares) # Prints [0, 1, 4, 9, 16]
even_squares = [x ** 2 for x in nums if x % 2 == 0] print(even_squares) # Prints "[0, 4, 16]"
- 字典 dictionaries,存儲(chǔ)鍵值對(duì)(key,value)
d = {'cat': 'cute', 'dog': 'furry'} # Create a new dictionary with some data print(d['cat']) # Get an entry from a dictionary; prints "cute" print('cat' in d) # Check if a dictionary has a given key; prints "True" d['fish'] = 'wet' # Set an entry in a dictionary print(d['fish']) # Prints "wet" # print(d['monkey']) # KeyError: 'monkey' not a key of d print(d.get('monkey', 'N/A')) # Get an element with a default; prints "N/A" print(d.get('fish', 'N/A')) # Get an element with a default; prints "wet" del d['fish'] # Remove an element from a dictionary print(d.get('fish', 'N/A')) # "fish" is no longer a key; prints "N/A"
字典循環(huán)
d = {'person': 2, 'cat': 4, 'spider': 8} print('A %s has %d legs' % (animal, legs)) # Prints "A person has 2 legs", "A cat has 4 legs", "A spider has 8 legs"
也可以利用內(nèi)建函數(shù)d.items()取得鍵和值
d = {'person': 2, 'cat': 4, 'spider': 8} for animal, legs in d.items(): print('A %s has %d legs' % (animal, legs)) # Prints "A person has 2 legs", "A cat has 4 legs", "A spider has 8 legs"
字典解析,利用表達(dá)式生成字典
even_num_to_square = {x: x ** 2 for x in nums if x % 2 == 0} print(even_num_to_square) # Prints "{0: 0, 2: 4, 4: 16}"
- 集合sets(注:集合中元素?zé)o序且不重復(fù))
print('cat' in animals) # Check if an element is in a set; prints "True" print('fish' in animals) # prints "False" animals.add('fish') # Add an element to a set print('fish' in animals) # Prints "True" print(len(animals)) # Number of elements in a set; prints "3" animals.add('cat') # Adding an element that is already in the set does nothing print(len(animals)) # Prints "3" animals.remove('cat') # Remove an element from a set print(len(animals)) # Prints "2"
集合循環(huán),與數(shù)組循環(huán)語(yǔ)法相同,但是注意其無(wú)序性。
animals = {'cat', 'dog', 'fish'} for idx, animal in enumerate(animals): print('#%d: %s' % (idx + 1, animal)) # Prints "#1: fish", "#2: dog", "#3: cat"
集合解析:利用解析表達(dá)式生成集合
nums = {int(sqrt(x)) for x in range(30)} print(nums) # Prints "{0, 1, 2, 3, 4, 5}"
- 元組 tuple,與數(shù)組類似,但其實(shí)不可變的列表,因此可以作為字典dictionary中的鍵key或集合set的元素(注:列表由于可變無(wú)法成為dictionary的key和set的元素)
d = {(x, x + 1): x for x in range(10)} # Create a dictionary with tuple keys t = (5, 6) # Create a tuple print(type(t)) # Prints "<class 'tuple'>" print(d[(1, 2)]) # Prints "1"
Python函數(shù)
利用關(guān)鍵字def,返回使用return
# Prints "negative", "zero", "positive"
參數(shù)可以使可選的的例子
def hello(name, loud=False): print('HELLO, %s!' % name.upper()) print('Hello, %s' % name) hello('Bob') # Prints "Hello, Bob" hello('Fred', loud=True) # Prints "HELLO, FRED!"
Python類
定義類的Python語(yǔ)法的格式如下
def __init__(self, name): self.name = name # Create an instance variable def greet(self, loud=False): print('HELLO, %s!' % self.name.upper()) print('Hello, %s' % self.name) g = Greeter('Fred') # 構(gòu)造Greeter類的實(shí)例 g.greet() # 調(diào)用類函數(shù);prints "Hello, Fred" g.greet(loud=True) # 調(diào)用類函數(shù); prints "HELLO, FRED!"
Numpy
numpy庫(kù)用于python科學(xué)計(jì)算,與matlab有相似之處,其核心是對(duì)數(shù)組arrays的操作。
數(shù)組arrays
數(shù)組array是numpy提供的容器,能夠通過(guò)列表list生成,利用方括號(hào)取元素(注:下標(biāo)從0開始)
a = np.array([1, 2, 3]) # Create a rank 1 array print(type(a)) # Prints "<class 'numpy.ndarray'>" print(a.shape) # Prints "(3,)" print(a[0], a[1], a[2]) # Prints "1 2 3" a[0] = 5 # Change an element of the array print(a) # Prints "[5, 2, 3]" b = np.array([[1,2,3],[4,5,6]]) # Create a rank 2 array print(b.shape) # Prints "(2, 3)" print(b[0, 0], b[0, 1], b[1, 0]) # Prints "1 2 4"
與matlab類似,numpy提供了一些生成特殊數(shù)組的函數(shù)
a = np.zeros((2,2)) # Create an array of all zeros print(a) # Prints "[[ 0. 0.] b = np.ones((1,2)) # Create an array of all ones print(b) # Prints "[[ 1. 1.]]" c = np.full((2,2), 7) # Create a constant array print(c) # Prints "[[ 7. 7.] d = np.eye(2) # Create a 2x2 identity matrix print(d) # Prints "[[ 1. 0.] e = np.random.random((2,2)) # Create an array filled with random values print(e) # Might print "[[ 0.91940167 0.08143941] # [ 0.68744134 0.87236687]]"
數(shù)組切片,利用方括號(hào)內(nèi)的逗號(hào)和冒號(hào)對(duì)每個(gè)維度進(jìn)行索引,基本與matlab相同(注:左包括右不包括)
# Create the following rank 2 array with shape (3, 4) a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) # Use slicing to pull out the subarray consisting of the first 2 rows # and columns 1 and 2; b is the following array of shape (2, 2): # A slice of an array is a view into the same data, so modifying it # will modify the original array. print(a[0, 1]) # Prints "2" b[0, 0] = 77 # b[0, 0] is the same piece of data as a[0, 1] print(a[0, 1]) # Prints "77"
與matlab不同的是,切片時(shí)使用單個(gè)數(shù)字索引和使用冒號(hào)的索引的結(jié)果維度是不同的,例如
# Create the following rank 2 array with shape (3, 4) a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) # Two ways of accessing the data in the middle row of the array. # Mixing integer indexing with slices yields an array of lower rank, # while using only slices yields an array of the same rank as the row_r1 = a[1, :] # Rank 1 view of the second row of a row_r2 = a[1:2, :] # Rank 2 view of the second row of a print(row_r1, row_r1.shape) # Prints "[5 6 7 8] (4,)" print(row_r2, row_r2.shape) # Prints "[[5 6 7 8]] (1, 4)" # We can make the same distinction when accessing columns of an array: print(col_r1, col_r1.shape) # Prints "[ 2 6 10] (3,)" print(col_r2, col_r2.shape) # Prints "[[ 2]
這里有一個(gè)較為奇怪的整數(shù)索引的方式,但這種表達(dá)方便創(chuàng)建數(shù)組。
a = np.array([[1,2], [3, 4], [5, 6]]) # An example of integer array indexing. # The returned array will have shape (3,) and print(a[[0, 1, 2], [0, 1, 0]]) # Prints "[1 4 5]" # The above example of integer array indexing is equivalent to this: print(np.array([a[0, 0], a[1, 1], a[2, 0]])) # Prints "[1 4 5]" # When using integer array indexing, you can reuse the same # element from the source array: print(a[[0, 0], [1, 1]]) # Prints "[2 2]" # Equivalent to the previous integer array indexing example print(np.array([a[0, 1], a[0, 1]])) # Prints "[2 2]"
# Create a new array from which we will select elements a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]]) print(a) # prints "array([[ 1, 2, 3], # Create an array of indices b = np.array([0, 2, 0, 1]) # Select one element from each row of a using the indices in b print(a[np.arange(4), b]) # Prints "[ 1 6 7 11]" # Mutate one element from each row of a using the indices in b print(a) # prints "array([[11, 2, 3],
利用布爾表達(dá)式進(jìn)行索引
a = np.array([[1,2], [3, 4], [5, 6]]) bool_idx = (a > 2) # Find the elements of a that are bigger than 2; # this returns a numpy array of Booleans of the same # shape as a, where each slot of bool_idx tells # whether that element of a is > 2. print(bool_idx) # Prints "[[False False] # We use boolean array indexing to construct a rank 1 array # consisting of the elements of a corresponding to the True values print(a[bool_idx]) # Prints "[3 4 5 6]" # We can do all of the above in a single concise statement: print(a[a > 2]) # Prints "[3 4 5 6]"
關(guān)于數(shù)組的索引就只介紹一小部分,當(dāng)有需要時(shí)請(qǐng)查看官方文檔深入學(xué)習(xí)。https://docs./doc/numpy/reference/arrays.indexing.html
數(shù)組的元素類型可以根據(jù)需求進(jìn)行定義
x = np.array([1, 2]) # Let numpy choose the datatype print(x.dtype) # Prints "int64" x = np.array([1.0, 2.0]) # Let numpy choose the datatype print(x.dtype) # Prints "float64" x = np.array([1, 2], dtype=np.int64) # Force a particular datatype print(x.dtype) # Prints "int64"
array的數(shù)學(xué)運(yùn)算,(注意與matlab不同,乘除法是每一個(gè)位置的元素乘除法,不是矩陣運(yùn)算)
x = np.array([[1,2],[3,4]], dtype=np.float64) y = np.array([[5,6],[7,8]], dtype=np.float64) # Elementwise sum; both produce the array # Elementwise difference; both produce the array # Elementwise product; both produce the array # Elementwise division; both produce the array # Elementwise square root; produces the array
矩陣乘法采用dot
x = np.array([[1,2],[3,4]]) y = np.array([[5,6],[7,8]]) # Inner product of vectors; both produce 219 # Matrix / vector product; both produce the rank 1 array [29 67] # Matrix / matrix product; both produce the rank 2 array
一些有用的矩陣運(yùn)算方法,例如sum
x = np.array([[1,2],[3,4]]) print(np.sum(x)) # Compute sum of all elements; prints "10" print(np.sum(x, axis=0)) # Compute sum of each column; prints "[4 6]" print(np.sum(x, axis=1)) # Compute sum of each row; prints "[3 7]"
當(dāng)需要使用某些函數(shù)時(shí),進(jìn)行搜索https://docs./doc/numpy/reference/routines.math.html
矩陣轉(zhuǎn)置
x = np.array([[1,2], [3,4]]) print(x) # Prints "[[1 2] print(x.T) # Prints "[[1 3] # Note that taking the transpose of a rank 1 array does nothing: print(v) # Prints "[1 2 3]" print(v.T) # Prints "[1 2 3]"
廣播機(jī)制:numpy中一個(gè)重要而有用的機(jī)制,可以將小的矩陣進(jìn)行擴(kuò)展后與大矩陣進(jìn)行運(yùn)算,省for循環(huán),提高運(yùn)算速度。
# We will add the vector v to each row of the matrix x, # storing the result in the matrix y x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]]) y = np.empty_like(x) # Create an empty matrix with the same shape as x # Add the vector v to each row of the matrix x with an explicit loop
# We will add the vector v to each row of the matrix x, # storing the result in the matrix y x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]]) vv = np.tile(v, (4, 1)) # Stack 4 copies of v on top of each other print(vv) # Prints "[[1 0 1] y = x + vv # Add x and vv elementwise print(y) # Prints "[[ 2 2 4
還能更加簡(jiǎn)潔
# We will add the vector v to each row of the matrix x, # storing the result in the matrix y x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]]) y = x + v # Add v to each row of x using broadcasting print(y) # Prints "[[ 2 2 4]
我們整理一些廣播broadcasting的規(guī)則:
1、兩個(gè)數(shù)組的維數(shù)不相同,低維度的擴(kuò)展維度
2、兩個(gè)數(shù)組在某個(gè)維度上size相同或小的size是1
3、廣播相當(dāng)于沿著size為1的地方進(jìn)行復(fù)制
下面用例子來(lái)展示一下廣播
# Compute outer product of vectors v = np.array([1,2,3]) # v has shape (3,) w = np.array([4,5]) # w has shape (2,) # To compute an outer product, we first reshape v to be a column # vector of shape (3, 1); we can then broadcast it against w to yield # an output of shape (3, 2), which is the outer product of v and w: print(np.reshape(v, (3, 1)) * w) # Add a vector to each row of a matrix x = np.array([[1,2,3], [4,5,6]]) # x has shape (2, 3) and v has shape (3,) so they broadcast to (2, 3), # giving the following matrix: # Add a vector to each column of a matrix # x has shape (2, 3) and w has shape (2,). # If we transpose x then it has shape (3, 2) and can be broadcast # against w to yield a result of shape (3, 2); transposing this result # yields the final result of shape (2, 3) which is the matrix x with # the vector w added to each column. Gives the following matrix: # Another solution is to reshape w to be a column vector of shape (2, 1); # we can then broadcast it directly against x to produce the same print(x + np.reshape(w, (2, 1))) # Multiply a matrix by a constant: # x has shape (2, 3). Numpy treats scalars as arrays of shape (); # these can be broadcast together to shape (2, 3), producing the
更多關(guān)于Numpy的內(nèi)容,請(qǐng)看官方文件http://docs./doc/numpy/reference/
SciPy
SciPy庫(kù)基于Numpy庫(kù),提供了許多操作數(shù)組array的函數(shù),官方文件http://docs./doc/scipy/reference/index.html
圖片操作
from scipy.misc import imread, imsave, imresize # Read an JPEG image into a numpy array img = imread('assets/cat.jpg') print(img.dtype, img.shape) # Prints "uint8 (400, 248, 3)" # We can tint the image by scaling each of the color channels # by a different scalar constant. The image has shape (400, 248, 3); # we multiply it by the array [1, 0.95, 0.9] of shape (3,); # numpy broadcasting means that this leaves the red channel unchanged, # and multiplies the green and blue channels by 0.95 and 0.9 img_tinted = img * [1, 0.95, 0.9] # Resize the tinted image to be 300 by 300 pixels. img_tinted = imresize(img_tinted, (300, 300)) # Write the tinted image back to disk imsave('assets/cat_tinted.jpg', img_tinted)
 
讀寫matlab文件
scipy.io.loadmat 與scipy.io.savemat,用到請(qǐng)看http://docs./doc/scipy/reference/io.html
’計(jì)算點(diǎn)間距離
from scipy.spatial.distance import pdist, squareform # Create the following array where each row is a point in 2D space: x = np.array([[0, 1], [1, 0], [2, 0]]) # Compute the Euclidean distance between all rows of x. # d[i, j] is the Euclidean distance between x[i, :] and x[j, :], # and d is the following array: # [[ 0. 1.41421356 2.23606798] d = squareform(pdist(x, 'euclidean'))
Matplotlib
matplotlib.pyplot的作圖模塊,與matlab中的使用類似
import matplotlib.pyplot as plt # Compute the x and y coordinates for points on a sine curve x = np.arange(0, 3 * np.pi, 0.1) # Plot the points using matplotlib plt.show() # You must call plt.show() to make graphics appear.

多條曲線、圖標(biāo)題、圖例、坐標(biāo)等
import matplotlib.pyplot as plt # Compute the x and y coordinates for points on sine and cosine curves x = np.arange(0, 3 * np.pi, 0.1) # Plot the points using matplotlib plt.xlabel('x axis label') plt.ylabel('y axis label') plt.title('Sine and Cosine') plt.legend(['Sine', 'Cosine'])

與matlab相同,利用subplot分區(qū)域作圖
import matplotlib.pyplot as plt # Compute the x and y coordinates for points on sine and cosine curves x = np.arange(0, 3 * np.pi, 0.1) # Set up a subplot grid that has height 2 and width 1, # and set the first such subplot as active. # Set the second subplot as active, and make the second plot.

顯示圖像
from scipy.misc import imread, imresize import matplotlib.pyplot as plt img = imread('assets/cat.jpg') img_tinted = img * [1, 0.95, 0.9] # Show the original image # A slight gotcha with imshow is that it might give strange results # if presented with data that is not uint8. To work around this, we # explicitly cast the image to uint8 before displaying it. plt.imshow(np.uint8(img_tinted))

|