Blog: https://blog.yilon.tophtml
咱们将在本课程的全部做业中使用Python编程语言。Python自己就是一种伟大的通用编程语言,而且它在一些其余流行的Python库(numpy、sciy、matplotlib)的帮助下,它成为了一个强大的科学计算环境。python
咱们但愿大家中大部分人会有一点Python和numpy的使用经验;由于对于大部分人来讲,本节将做为关于Python编程语言和使用Python进行科学计算的快速速成课程。git
大家中的一些人可能之前学过Matlab接触过相关的知识,若是是这样的话,我推荐大家看一下这篇文章:Numpy对于Matlab用户。github
你还能够在 这里找到 由 Volodymyr Kuleshov 和 Isaac Caswell 为 CS 228 建立的本教程的IPython笔记版本。web
目录:算法
Python是一种高级动态类型的多范式编程语言。Python代码一般被称为可运行的伪代码,由于它容许你在很是少的代码行中表达很是强大的想法,同时具备很是可读性。做为示例,这里是Python中经典快速排序算法的实现:编程
def quicksort(arr): if len(arr) <= 1: return arr pivot = arr[len(arr) // 2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quicksort(left) + middle + quicksort(right) print(quicksort([3,6,8,10,1,2,1])) # Prints "[1, 1, 2, 3, 6, 8, 10]"
目前有两种不一样的受支持版本的Python,分别是2.7和3.5。有点使人困惑的是,Python 3.0引入了许多向后兼容的语言更改,所以为2.7编写的代码可能没法在3.5下运行,反之亦然。因此咱们下面全部的示例的代码都使用Python 3.5来编程。api
你能够经过运行 python -version
在命令行中查看Python的版本。数组
与大多数语言同样,Python有许多基本类型,包括整数,浮点数,布尔值和字符串。这些数据类型的行为方式与其余编程语言类似。app
Numbers(数字类型):表明的是整数和浮点数,它原理与其余语言相同:
x = 3 print(type(x)) # Prints "<class 'int'>" print(x) # Prints "3" print(x + 1) # Addition; prints "4" print(x - 1) # Subtraction; prints "2" print(x * 2) # Multiplication; prints "6" print(x ** 2) # Exponentiation; prints "9" x += 1 print(x) # Prints "4" x *= 2 print(x) # Prints "8" y = 2.5 print(type(y)) # Prints "<class 'float'>" print(y, y + 1, y * 2, y ** 2) # Prints "2.5 3.5 5.0 6.25"
注意,与许多语言不一样,Python没有一元增量(x+
)或递减(x-
)运算符。
Python还有用于复数的内置类型;你能够在这篇文档中找到全部的详细信息。
Booleans(布尔类型): Python实现了全部经常使用的布尔逻辑运算符,但它使用的是英文单词而不是符号 (&&
, ||
, etc.):
t = True f = False print(type(t)) # Prints "<class 'bool'>" print(t and f) # Logical AND; prints "False" print(t or f) # Logical OR; prints "True" print(not t) # Logical NOT; prints "False" print(t != f) # Logical XOR; prints "True"
Strings(字符串类型):Python对字符串有很好的支持:
hello = 'hello' # String literals can use single quotes world = "world" # or double quotes; it does not matter. print(hello) # Prints "hello" print(len(hello)) # String length; prints "5" hw = hello + ' ' + world # String concatenation print(hw) # prints "hello world" hw12 = '%s %s %d' % (hello, world, 12) # sprintf style string formatting print(hw12) # prints "hello world 12"
String对象有许多有用的方法;例如:
s = "hello" print(s.capitalize()) # Capitalize a string; prints "Hello" print(s.upper()) # Convert a string to uppercase; prints "HELLO" print(s.rjust(7)) # Right-justify a string, padding with spaces; prints " hello" print(s.center(7)) # Center a string, padding with spaces; prints " hello " print(s.replace('l', '(ell)')) # Replace all instances of one substring with another; # prints "he(ell)(ell)o" print(' world '.strip()) # Strip leading and trailing whitespace; prints "world"
你能够在这篇文档中找到全部String方法的列表。
Python包含几种内置的容器类型:列表、字典、集合和元组。
列表其实就是Python中的数组,可是能够它能够动态的调整大小而且能够包含不一样类型的元素:
xs = [3, 1, 2] # Create a list print(xs, xs[2]) # Prints "[3, 1, 2] 2" print(xs[-1]) # Negative indices count from the end of the list; prints "2" xs[2] = 'foo' # Lists can contain elements of different types print(xs) # Prints "[3, 1, 'foo']" xs.append('bar') # Add a new element to the end of the list print(xs) # Prints "[3, 1, 'foo', 'bar']" x = xs.pop() # Remove and return the last element of the list print(x, xs) # Prints "bar [3, 1, 'foo']"
像往常同样,你能够在这篇文档中找到有关列表的全部详细信息。
切片(Slicing): 除了一次访问一个列表元素以外,Python还提供了访问子列表的简明语法; 这被称为切片:
nums = list(range(5)) # range is a built-in function that creates a list of integers print(nums) # Prints "[0, 1, 2, 3, 4]" print(nums[2:4]) # Get a slice from index 2 to 4 (exclusive); prints "[2, 3]" print(nums[2:]) # Get a slice from index 2 to the end; prints "[2, 3, 4]" print(nums[:2]) # Get a slice from the start to index 2 (exclusive); prints "[0, 1]" print(nums[:]) # Get a slice of the whole list; prints "[0, 1, 2, 3, 4]" print(nums[:-1]) # Slice indices can be negative; prints "[0, 1, 2, 3]" nums[2:4] = [8, 9] # Assign a new sublist to a slice print(nums) # Prints "[0, 1, 8, 9, 4]"
咱们将在numpy数组的上下文中再次看到切片。
(循环)Loops: 你能够循环遍历列表的元素,以下所示:
animals = ['cat', 'dog', 'monkey'] for animal in animals: print(animal) # Prints "cat", "dog", "monkey", each on its own line.
若是要访问循环体内每一个元素的索引,请使用内置的 enumerate
函数:
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
列表推导式(List comprehensions): 编程时,咱们常常想要将一种数据转换为另外一种数据。 举个简单的例子,思考如下计算平方数的代码:
nums = [0, 1, 2, 3, 4] squares = [] for x in nums: squares.append(x ** 2) print(squares) # Prints [0, 1, 4, 9, 16]
你可使用 列表推导式 使这段代码更简单:
nums = [0, 1, 2, 3, 4] squares = [x ** 2 for x in nums] print(squares) # Prints [0, 1, 4, 9, 16]
列表推导还能够包含条件:
nums = [0, 1, 2, 3, 4] even_squares = [x ** 2 for x in nums if x % 2 == 0] print(even_squares) # Prints "[0, 4, 16]"
字典存储(键,值)对,相似于Java中的Map
或Javascript中的对象。你能够像这样使用它:
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"
你能够在这篇文档中找到有关字典的全部信息。
(循环)Loops: 迭代词典中的键很容易:
d = {'person': 2, 'cat': 4, 'spider': 8} for animal in d: legs = d[animal] print('A %s has %d legs' % (animal, legs)) # Prints "A person has 2 legs", "A cat has 4 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)) # Prints "A person has 2 legs", "A cat has 4 legs", "A spider has 8 legs"
字典推导式(Dictionary comprehensions): 相似于列表推导式,可让你轻松构建词典数据类型。例如:
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) # Prints "{0: 0, 2: 4, 4: 16}"
集合是不一样元素的无序集合。举个简单的例子,请思考下面的代码:
animals = {'cat', 'dog'} 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"
与往常同样,你想知道的关于集合的全部内容均可以在这篇文档中找到。
循环(Loops): 遍历集合的语法与遍历列表的语法相同;可是,因为集合是无序的,所以不能假设访问集合元素的顺序:
animals = {'cat', 'dog', 'fish'} for idx, animal in enumerate(animals): print('#%d: %s' % (idx + 1, animal)) # Prints "#1: fish", "#2: dog", "#3: cat"
集合推导式(Set comprehensions): 就像列表和字典同样,咱们能够很容易地使用集合理解来构造集合:
from math import sqrt nums = {int(sqrt(x)) for x in range(30)} print(nums) # Prints "{0, 1, 2, 3, 4, 5}"
元组是(不可变的)有序值列表。 元组在不少方面相似于列表; 其中一个最重要的区别是元组能够用做字典中的键和集合的元素,而列表则不能。 这是一个简单的例子:
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[t]) # Prints "5" print(d[(1, 2)]) # Prints "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)) # Prints "negative", "zero", "positive"
咱们常常定义函数来获取可选的关键字参数,以下所示:
def hello(name, loud=False): if loud: print('HELLO, %s!' % name.upper()) else: print('Hello, %s' % name) hello('Bob') # Prints "Hello, Bob" hello('Fred', loud=True) # Prints "HELLO, FRED!"
这篇文档中有更多关于Python函数的信息。
在Python中定义类的语法很简单:
class Greeter(object): # Constructor def __init__(self, name): self.name = name # Create an instance variable # Instance method def greet(self, loud=False): if loud: print('HELLO, %s!' % self.name.upper()) else: print('Hello, %s' % self.name) g = Greeter('Fred') # Construct an instance of the Greeter class g.greet() # Call an instance method; prints "Hello, Fred" g.greet(loud=True) # Call an instance method; prints "HELLO, FRED!"
你能够在这篇文档中阅读更多关于Python类的内容。
Numpy是Python中科学计算的核心库。它提供了一个高性能的多维数组对象,以及用于处理这些数组的工具。若是你已经熟悉MATLAB,你可能会发现这篇教程对于你从MATLAB切换到学习Numpy颇有帮助。
numpy数组是一个值网格,全部类型都相同,并由非负整数元组索引。 维数是数组的排名; 数组的形状是一个整数元组,给出了每一个维度的数组大小。
咱们能够从嵌套的Python列表初始化numpy数组,并使用方括号访问元素:
import numpy as np 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"
Numpy还提供了许多建立数组的函数:
import numpy as np a = np.zeros((2,2)) # Create an array of all zeros print(a) # Prints "[[ 0. 0.] # [ 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.] # [ 7. 7.]]" d = np.eye(2) # Create a 2x2 identity matrix print(d) # Prints "[[ 1. 0.] # [ 0. 1.]]" 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]]"
你能够在这篇文档中阅读有关其余数组建立方法的信息。
Numpy提供了几种索引数组的方法。
切片(Slicing): 与Python列表相似,能够对numpy数组进行切片。因为数组多是多维的,所以必须为数组的每一个维指定一个切片:
import numpy as np # Create the following rank 2 array with shape (3, 4) # [[ 1 2 3 4] # [ 5 6 7 8] # [ 9 10 11 12]] 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): # [[2 3] # [6 7]] b = a[:2, 1:3] # 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处理数组切片的方式彻底不一样:
import numpy as np # Create the following rank 2 array with shape (3, 4) # [[ 1 2 3 4] # [ 5 6 7 8] # [ 9 10 11 12]] 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 # original array: 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: col_r1 = a[:, 1] col_r2 = a[:, 1:2] print(col_r1, col_r1.shape) # Prints "[ 2 6 10] (3,)" print(col_r2, col_r2.shape) # Prints "[[ 2] # [ 6] # [10]] (3, 1)"
整数数组索引: 使用切片索引到numpy数组时,生成的数组视图将始终是原始数组的子数组。 相反,整数数组索引容许你使用另外一个数组中的数据构造任意数组。 这是一个例子:
import numpy as np 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]"
整数数组索引的一个有用技巧是从矩阵的每一行中选择或改变一个元素:
import numpy as np # 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], # [ 4, 5, 6], # [ 7, 8, 9], # [10, 11, 12]])" # 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 a[np.arange(4), b] += 10 print(a) # prints "array([[11, 2, 3], # [ 4, 5, 16], # [17, 8, 9], # [10, 21, 12]])
布尔数组索引: 布尔数组索引容许你选择数组的任意元素。一般,这种类型的索引用于选择知足某些条件的数组元素。下面是一个例子:
import numpy as np 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] # [ True True] # [ True True]]" # We use boolean array indexing to construct a rank 1 array # consisting of the elements of a corresponding to the True values # of bool_idx 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]"
为简洁起见,咱们省略了不少关于numpy数组索引的细节; 若是你想了解更多,你应该阅读这篇文档。
每一个numpy数组都是相同类型元素的网格。Numpy提供了一组可用于构造数组的大量数值数据类型。Numpy在建立数组时尝试猜想数据类型,但构造数组的函数一般还包含一个可选参数来显式指定数据类型。这是一个例子:
import numpy as np 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"
你能够在这篇文档中阅读有关numpy数据类型的全部信息。
基本数学函数在数组上以元素方式运行,既能够做为运算符重载,也能够做为numpy模块中的函数:
import numpy as np 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 # [[ 6.0 8.0] # [10.0 12.0]] print(x + y) print(np.add(x, y)) # Elementwise difference; both produce the array # [[-4.0 -4.0] # [-4.0 -4.0]] print(x - y) print(np.subtract(x, y)) # Elementwise product; both produce the array # [[ 5.0 12.0] # [21.0 32.0]] print(x * y) print(np.multiply(x, y)) # Elementwise division; both produce the array # [[ 0.2 0.33333333] # [ 0.42857143 0.5 ]] print(x / y) print(np.divide(x, y)) # Elementwise square root; produces the array # [[ 1. 1.41421356] # [ 1.73205081 2. ]] print(np.sqrt(x))
请注意,与MATLAB不一样,*
是元素乘法,而不是矩阵乘法。 咱们使用dot
函数来计算向量的内积,将向量乘以矩阵,并乘以矩阵。 dot
既能够做为numpy模块中的函数,也能够做为数组对象的实例方法:
import numpy as np x = np.array([[1,2],[3,4]]) y = np.array([[5,6],[7,8]]) v = np.array([9,10]) w = np.array([11, 12]) # Inner product of vectors; both produce 219 print(v.dot(w)) print(np.dot(v, w)) # Matrix / vector product; both produce the rank 1 array [29 67] print(x.dot(v)) print(np.dot(x, v)) # Matrix / matrix product; both produce the rank 2 array # [[19 22] # [43 50]] print(x.dot(y)) print(np.dot(x, y))
Numpy为在数组上执行计算提供了许多有用的函数;其中最有用的函数之一是 SUM
:
import numpy as np 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]"
你能够在这篇文档中找到numpy提供的数学函数的完整列表。
除了使用数组计算数学函数外,咱们常常须要对数组中的数据进行整形或其余操做。这种操做的最简单的例子是转置一个矩阵;要转置一个矩阵,只需使用一个数组对象的T
属性:
import numpy as np x = np.array([[1,2], [3,4]]) print(x) # Prints "[[1 2] # [3 4]]" print(x.T) # Prints "[[1 3] # [2 4]]" # Note that taking the transpose of a rank 1 array does nothing: v = np.array([1,2,3]) print(v) # Prints "[1 2 3]" print(v.T) # Prints "[1 2 3]"
Numpy提供了许多用于操做数组的函数;你能够在这篇文档中看到完整的列表。
广播是一种强大的机制,它容许numpy在执行算术运算时使用不一样形状的数组。一般,咱们有一个较小的数组和一个较大的数组,咱们但愿屡次使用较小的数组来对较大的数组执行一些操做。
例如,假设咱们要向矩阵的每一行添加一个常数向量。咱们能够这样作:
import numpy as np # 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]]) v = np.array([1, 0, 1]) 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 for i in range(4): y[i, :] = x[i, :] + v # Now y is the following # [[ 2 2 4] # [ 5 5 7] # [ 8 8 10] # [11 11 13]] print(y)
这会凑效; 可是当矩阵 x
很是大时,在Python中计算显式循环可能会很慢。注意,向矩阵 x
的每一行添加向量 v
等同于经过垂直堆叠多个 v
副原本造成矩阵 vv
,而后执行元素的求和x
和 vv
。 咱们能够像以下这样实现这种方法:
import numpy as np # 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]]) v = np.array([1, 0, 1]) vv = np.tile(v, (4, 1)) # Stack 4 copies of v on top of each other print(vv) # Prints "[[1 0 1] # [1 0 1] # [1 0 1] # [1 0 1]]" y = x + vv # Add x and vv elementwise print(y) # Prints "[[ 2 2 4 # [ 5 5 7] # [ 8 8 10] # [11 11 13]]"
Numpy广播容许咱们在不实际建立v
的多个副本的状况下执行此计算。考虑这个需求,使用广播以下:
import numpy as np # 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]]) v = np.array([1, 0, 1]) y = x + v # Add v to each row of x using broadcasting print(y) # Prints "[[ 2 2 4] # [ 5 5 7] # [ 8 8 10] # [11 11 13]]"
y=x+v
行即便x
具备形状(4,3)
和v
具备形状(3,)
,但因为广播的关系,该行的工做方式就好像v
实际上具备形状(4,3)
,其中每一行都是v
的副本,而且求和是按元素执行的。
将两个数组一块儿广播遵循如下规则:
若是对于以上的解释依然没有理解,请尝试阅读这篇文档或这篇解释中的说明。
支持广播的功能称为通用功能。你能够在这篇文档中找到全部通用功能的列表。
如下是广播的一些应用:
import numpy as np # 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: # [[ 4 5] # [ 8 10] # [12 15]] 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: # [[2 4 6] # [5 7 9]] print(x + v) # 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: # [[ 5 6 7] # [ 9 10 11]] print((x.T + w).T) # 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 # output. 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 # following array: # [[ 2 4 6] # [ 8 10 12]] print(x * 2)
广播一般会使你的代码更简洁,效率更高,所以你应该尽量地使用它。
这个简短的概述说明了部分numpy相关的重要事项。查看numpy参考手册以了解有关numpy的更多信息。
Numpy提供了一个高性能的多维数组和基本工具来计算和操做这些数组。 而SciPy以此为基础,提供了大量在numpy数组上运行的函数,可用于不一样类型的科学和工程应用程序。
熟悉SciPy的最佳方法是浏览它的文档。咱们将重点介绍SciPy有关的对你有价值的部份内容。
SciPy提供了一些处理图像的基本函数。例如,它具备将映像从磁盘读入numpy数组、将numpy数组做为映像写入磁盘以及调整映像大小的功能。下面是一个演示这些函数的简单示例:
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 # respectively. 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)
左:原始图像。右:着色和调整大小的图像。
函数 scipy.io.loadmat
和 scipy.io.savemat
容许你读取和写入MATLAB文件。你能够在这篇文档中学习相关操做。
SciPy定义了一些用于计算点集之间距离的有用函数。
函数scipy.spatial.distance.pdist
计算给定集合中全部点对之间的距离:
import numpy as np from scipy.spatial.distance import pdist, squareform # Create the following array where each row is a point in 2D space: # [[0 1] # [1 0] # [2 0]] x = np.array([[0, 1], [1, 0], [2, 0]]) print(x) # 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] # [ 1.41421356 0. 1. ] # [ 2.23606798 1. 0. ]] d = squareform(pdist(x, 'euclidean')) print(d)
你能够在这篇文档中阅读有关此功能的全部详细信息。
相似的函数(scipy.spatial.distance.cdist
)计算两组点之间全部对之间的距离; 你能够在这篇文档中阅读它。
Matplotlib是一个绘图库。本节简要介绍 matplotlib.pyplot
模块,该模块提供了相似于MATLAB的绘图系统。
matplotlib中最重要的功能是plot
,它容许你绘制2D数据的图像。这是一个简单的例子:
import numpy as np 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) y = np.sin(x) # Plot the points using matplotlib plt.plot(x, y) plt.show() # You must call plt.show() to make graphics appear.
运行此代码会生成如下图表:
经过一些额外的工做,咱们能够轻松地一次绘制多条线,并添加标题,图例和轴标签:
import numpy as np 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) y_sin = np.sin(x) y_cos = np.cos(x) # Plot the points using matplotlib plt.plot(x, y_sin) plt.plot(x, y_cos) plt.xlabel('x axis label') plt.ylabel('y axis label') plt.title('Sine and Cosine') plt.legend(['Sine', 'Cosine']) plt.show()
你能够在这篇文档中阅读有关绘图
功能的更多信息。
你可使用subplot
函数在同一个图中绘制不一样的东西。 这是一个例子:
import numpy as np 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) y_sin = np.sin(x) y_cos = np.cos(x) # Set up a subplot grid that has height 2 and width 1, # and set the first such subplot as active. plt.subplot(2, 1, 1) # Make the first plot plt.plot(x, y_sin) plt.title('Sine') # Set the second subplot as active, and make the second plot. plt.subplot(2, 1, 2) plt.plot(x, y_cos) plt.title('Cosine') # Show the figure. plt.show()
你能够在这篇文档中阅读有关子图
功能的更多信息。
你可使用 imshow
函数来显示一张图片。 这是一个例子:
import numpy as np 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 plt.subplot(1, 2, 1) plt.imshow(img) # Show the tinted image plt.subplot(1, 2, 2) # 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)) plt.show()
由NumPy中文文档翻译,原做者为 Justin Johnson,翻译至:http://cs231n.github.io/python-numpy-tutorial/。
Blog: https://blog.yilon.top