Python Numpy 教程(使用 Jupyter 和 Colab)
Colab 筆記本
本教程最初由Justin Johnson提供。
我們將在本課程的所有作業中使用 Python 編程語言。Python 本身就是一種出色的通用編程語言,但在一些流行的庫(numpy、scipy、matplotlib)的幫助下,它成為了一個強大的科學計算環境。
我們希望你們中的許多人對 Python 和 numpy 有一定的經驗;對于其他人來說,本節將作為 Python 編程語言及其在科學計算中的使用的速成課程。我們還將介紹筆記本,這是修改 Python 代碼的一種非常方便的方式。你們中的一些人可能有不同語言的先前知識,在這種情況下,我們還建議參考: Matlab 用戶的 NumPy、 R 用戶的 Python 和/或 SAS 用戶的 Python。
目錄
Jupyter 和 Colab 筆記本
Python
Python 版本
基本數據類型
容器
列表
字典
套
元組
職能
課程
麻木的
數組
數組索引
數據類型
數組數學
廣播
Numpy 文檔
科學派
圖像操作
MATLAB 文件
點之間的距離
Matplotlib
繪圖
子圖
圖片
Jupyter 和 Colab 筆記本
在我們深入研究 Python 之前,我們想簡單地談談筆記本。Jupyter notebook 可讓您在 Web 瀏覽器中本地編寫和執行 Python 代碼。Jupyter notebook 讓修改代碼和零碎執行變得非常容易;因此,它們被廣泛用于科學計算。另一方面,Colab 是谷歌的 Jupyter 筆記本,特別適用于機器學習和數據分析,并且完全在云中運行。Colab 基本上是類固醇上的 Jupyter 筆記本:它是免費的,無需設置,預裝了許多軟件包,易于與世界共享,并受益于免費訪問 GPU 和 TPU 等硬件加速器(有一些警告)。
在 Colab 中運行教程(推薦)。如果您希望完全在 Colab 中運行本教程,請單擊Open in Colab此頁面頂部的徽章。
在 Jupyter Notebook 中運行教程。如果您希望使用 Jupyter 在本地運行 notebook,請確保您的虛擬環境已正確安裝(按照設置說明),激活它,然后運行pip install notebook以安裝 Jupyter notebook。接下來,打開筆記本并將其下載到您選擇的目錄,方法是右鍵單擊頁面并選擇Save Page As。然后cd到該目錄并運行jupyter notebook.
這應該會自動在http://localhost:8888. 如果一切正常,您應該會看到這樣的屏幕,顯示當前目錄中所有可用的筆記本。單擊jupyter-notebook-tutorial.ipynb 并按照筆記本中的說明進行操作。否則,您可以使用下面的代碼片段繼續閱讀本教程。
Python
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 版本
截至 2020 年 1 月 1 日,Python 已正式放棄對python2. 對于此類,所有代碼都將使用 Python 3.7。在繼續本教程之前,請確保您已完成設置說明 并正確安裝了虛擬環境。python3在激活環境后,您可以在命令行中仔細檢查您的 Python 版本,方法是運行python --version.
基本數據類型
與大多數語言一樣,Python 有許多基本類型,包括整數、浮點數、布爾值和字符串。這些數據類型的行為方式與其他編程語言相似。
數字:整數和浮點數的工作方式與您對其他語言的期望一樣:
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 還具有用于復數的內置類型;您可以在文檔中找到所有詳細信息 。
布爾值: Python 實現了布爾邏輯的所有常用運算符,但使用英文單詞而不是符號(&&、||等):
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”
字符串: 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”
字符串對象有很多有用的方法;例如:
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”
您可以在文檔中找到所有字符串方法的列表。
容器
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’]”
像往常一樣,您可以在文檔中找到有關列表的所有詳細信息 。
切片: 除了一次訪問一個列表元素外,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 數組的上下文中再次看到切片。
循環:您可以像這樣循環列表的元素:
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
列表推導: 在編程時,我們經常希望將一種類型的數據轉換為另一種類型的數據。作為一個簡單的示例,請考慮以下計算平方數的代碼:
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]”
字典
字典存儲(鍵,值)對,類似于MapJava 中的 a 或 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”
您可以在文檔中找到所有您需要了解的有關字典 的信息。
循環:很容易遍歷字典中的鍵:
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”
字典推導: 這些類似于列表推導,但允許您輕松構建字典。例如:
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”
像往常一樣,你想知道的關于集合的一切都可以 在文檔中找到。
循環: 對集合進行迭代與對列表進行迭代具有相同的語法;但是,由于集合是無序的,因此您不能對訪問集合元素的順序做出假設:
animals = {‘cat’, ‘dog’, ‘fish’}
for idx, animal in enumerate(animals):
print(’#%d: %s’ % (idx + 1, animal))
Prints “#1: fish”, “#2: dog”, “#3: cat”
集合推導: 像列表和字典一樣,我們可以使用集合推導輕松構造集合:
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,您可能會發現 本教程對開始使用 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? # 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 提供了幾種索引數組的方法。
切片: 類似于 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 中計算顯式循環可能會很慢。請注意,將向量添加v到矩陣的每一行 相當于通過垂直堆疊多個副本x來形成矩陣,然后對和進行元素求和。我們可以像這樣實現這種方法:vvvxvv
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實際上有 shape一樣(4, 3),其中每一行都是 的副本v,并且總和是按元素執行的。
一起廣播兩個數組遵循以下規則:
如果數組的秩不同,則在較低秩數組的形狀前面加上 1,直到兩個形狀的長度相同。
如果兩個數組在一個維度上具有相同的大小,或者如果其中一個數組在該維度上的大小為 1,則稱這兩個數組在一個維度上是兼容的。
如果數組在所有維度上都兼容,則可以一起廣播。
廣播之后,每個數組的行為就好像它的形狀等于兩個輸入數組的形狀的元素最大值。
在一個數組的大小為 1 而另一個數組的大小大于 1 的任何維度中,第一個數組的行為就好像它是沿該維度復制的一樣
如果此解釋沒有意義,請嘗試閱讀 文檔 或此解釋中的解釋。
支持廣播的函數稱為通用函數。您可以在文檔中找到所有通用函數的列表 。
以下是廣播的一些應用:
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 的更多信息。
科學派
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)
左:原始圖像。右圖:著色和調整大小的圖像。
MATLAB 文件
函數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是一個繪圖庫。本節簡要介紹該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()
您可以在文檔中閱讀有關該plot功能 的更多信息。
子圖
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()
您可以在文檔中閱讀有關該subplot功能 的更多信息。
圖片
您可以使用該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()
總結
以上是生活随笔為你收集整理的Python Numpy 教程(使用 Jupyter 和 Colab)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MET 3P5: 工业工程
- 下一篇: RDC Hydrogen