A02_Python(基本数据类型,容器,函数,类),Numpy(数组array,数组索引,数据类型,数组中的数学,广播)
Python的版本
基本數據類型
與大多數語言一樣,Python有許多基本類型,包括整數,浮點數,布爾值和字符串。這些數據類型的行為方式與其他編程語言相似。
Numbers(數字類型):代表的是整數和浮點數,它原理與其他語言相同:
注意,與許多語言不同,Python沒有一元增量(x+)或遞減(x-)運算符。
Python還有用于復數的內置類型;你可以在這篇文檔中找到所有的詳細信息。
Booleans(布爾類型): Python實現了所有常用的布爾邏輯運算符,但它使用的是英文單詞而不是符號 (&&, ||, etc.):
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"容器(Containers)
Python包含幾種內置的容器類型:列表、字典、集合和元組。
列表(Lists)
列表其實就是Python中的數組,但是可以它可以動態的調整大小并且可以包含不同類型的元素:
我們將在numpy數組的上下文中再次看到切片
循環Loops:你可以循環遍歷列表的元素,如下所示:
如果要訪問循環體內每個元素的索引,請使用內置的 enumerate 函數:
animals = ['cat','dog','monkey'] for idx, animal in enumerate(animals):print('#%d: %s' % (idx + 1, animal))列表推導式(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中的對象。你可以像這樣使用過它:
(循環)Loops:迭代詞典中的鍵很容易:
d = {"person":2,'cat':4,'spider':8} for animal in d:legs = d[animal]print('A %s has %d legs' % (animal,legs))運行結果:
A person has 2 legs A cat has 4 legs A spider has 8 legs如果要訪問鍵及其對應的值,請使用items方法:
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)集合(Sets)
集合是不同元素的無序集合。舉個簡單的例子,請思考下面的代碼:
循環(Loops):遍歷集合的語法與遍歷列表的語法相同;但是,由于集合是無序的,因此不能假設訪問集合元素的順序:
animals = {'cat','dog','fish'} for idx,animal in enumerate(animals):print('#%d:%s' % (idx + 1,animal))運行結果:
#1:dog #2:fish #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}"元組(Tuples)
元組是(不可變的)有序值列表。元組在很多類似于列表;其中一個重要的區別是元組可以用作字典中的鍵和集合的元素,而列表則不能。這是一個簡單的例子:
函數(Functions)
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') #Prints "Hello,Bob" hello('Fred',loud=True) #Prints "Hello,FRED!"運行結果:
Hello,Bob HELLO,FRED!類(Classes)
在Python中定義類的語法很簡單:
class Greeter(object):def __init__(self,name):self.name = name#Instance methoddef 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中科學計算的核心庫。它提供了一個高性能的多維數組對象,以及用于處理這些數組的工具。如果你已經熟悉MATLAB,你可能會發現這篇教程對于你從MATLAB切換到學習Numpy很有幫助。
數組(Arrays)
numpy數組是一個值網格,所有類型都相同,并由非負整數元組索引。 維數是數組的排名; 數組的形狀是一個整數元組,給出了每個維度的數組大小。
我們可以從嵌套的Python列表初始化numpy數組,并使用方括號訪問元素:
import numpy as npa = 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 npa = 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數組進行切片。由于數組可能是多維的,因此必須為數組的每個維指定一個切片:
你還可以將整數索引與切片索引混合使用。 但是,這樣做會產生比原始數組更低級別的數組。 請注意,這與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 npa = 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] += 10print(a) # prints "array([[11, 2, 3],# [ 4, 5, 16],# [17, 8, 9],# [10, 21, 12]])布爾數組索引: 布爾數組索引允許你選擇數組的任意元素。通常,這種類型的索引用于選擇滿足某些條件的數組元素。下面是一個例子:
import numpy as npa = 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在創建數組時嘗試猜測數據類型,但構造數組的函數通常還包含一個可選參數來顯式指定數據類型。這是一個例子:
import numpy as npx = np.array([1, 2]) # Let numpy choose the datatype print(x.dtype) # Prints "int32"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模塊中的函數:
import numpy as npx = 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 npx = 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 npx = 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]"除了使用數組計算數學函數外,我們經常需要對數組中的數據進行整形或其他操作。這種操作的最簡單的例子是轉置一個矩陣;要轉置一個矩陣,只需使用一個數組對象的T屬性:
import numpy as npx = 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]"廣播(Broadcasting)
廣播是一種強大的機制,它允許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的副本,并且求和是按元素執行的。
將兩個數組一起廣播遵循以下規則:
如果數組不具有相同的rank,則將較低等級數組的形狀添加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)總結
以上是生活随笔為你收集整理的A02_Python(基本数据类型,容器,函数,类),Numpy(数组array,数组索引,数据类型,数组中的数学,广播)的全部內容,希望文章能夠幫你解決所遇到的問題。