Python Numpy 快速入門

Python

Python是一種高級(jí)的、動(dòng)態(tài)類型的多范型編程語(yǔ)言。Python代碼通常被認(rèn)為是偽代碼,因?yàn)樗试S您在非常可讀的幾行代碼中表達(dá)非常強(qiáng)大的思想。作為一個(gè)例子,下面是Python中經(jīng)典的快速排序算法的實(shí)現(xiàn):

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版本

目前有兩種不同的Python版本,分別是2.7和3.5。Python 3.0引入了許多對(duì)語(yǔ)言不兼容的更改,因此為2.7編寫的代碼可能不能在3.5下工作。
您可以通過運(yùn)行Python-version來(lái)檢查命令行中的Python版本。

基本數(shù)據(jù)類型

與大多數(shù)語(yǔ)言一樣,Python有許多基本類型,包括整數(shù)、浮點(diǎn)數(shù)、布爾值和字符串。這些數(shù)據(jù)類型的使用方式與其他編程語(yǔ)言很相似。
數(shù)字:整數(shù)和浮點(diǎn)數(shù)可以從其他語(yǔ)言中得到:

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"

注意,與許多語(yǔ)言不同的是,Python不支持增量(x++)或遞減(x--)操作符。
Python也有用于復(fù)數(shù)的內(nèi)置類型;您可以在文檔中找到所有的細(xì)節(jié)。

布爾值:Python實(shí)現(xiàn)了布爾邏輯的所有常用操作符,但使用的是英語(yǔ)單詞而不是符號(hào)(&&等等):

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對(duì)字符串有很大的支持:

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對(duì)象有很多有用的方法;例如:

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包括幾個(gè)內(nèi)置的容器類型:列表、字典、集合和元組。

列表
列表是Python的一個(gè)數(shù)組,但是可以調(diào)整,并且可以包含不同類型的元素:

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還提供了訪問子列表的簡(jiǎn)明語(yǔ)法;這就是所謂的切片:

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]"

循環(huán):您可以對(duì)列表的元素進(jìn)行循環(huán)/遍歷:

animals = ['cat', 'dog', 'monkey']
for animal in animals:
    print(animal)
# Prints "cat", "dog", "monkey", each on its own line.

如果您想要訪問循環(huán)體中的每個(gè)元素的索引,請(qǐng)使用內(nèi)置的枚舉(enumerate)函數(shù):

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

列表理解:在編程時(shí),我們經(jīng)常需要將一種類型的數(shù)據(jù)轉(zhuǎn)換為另一種類型。作為一個(gè)簡(jiǎn)單的例子,考慮下面的代碼計(jì)算平方數(shù):

nums = [0, 1, 2, 3, 4]
squares = []
for x in nums:
    squares.append(x ** 2)
print(squares)   # Prints [0, 1, 4, 9, 16]

您可以使用列表理解來(lái)簡(jiǎn)化這段代碼:

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]"

字典
字典存儲(chǔ)(鍵、值)對(duì),類似于Java中的映射或Javascript中的對(duì)象。你可以這樣使用它:

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):在字典中對(duì)鍵進(jìn)行迭代是很容易的:

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"

如果您想要訪問鍵值(keys)及其對(duì)應(yīng)的值,請(qǐng)使用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"

字典的理解:這些類似于列表的理解,但是允許你輕松地構(gòu)造字典。例如:

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}"

集合
集合是不同元素的無(wú)序集合。作為一個(gè)簡(jiǎn)單的例子,請(qǐng)考慮以下內(nèi)容:

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"

循環(huán):在一個(gè)集合上的迭代與遍歷列表的語(yǔ)法相同;然而,由于集合是無(wú)序的,所以您不能對(duì)您訪問集合元素的順序作出假設(shè):

animals = {'cat', 'dog', 'fish'}
for idx, animal in enumerate(animals):
    print('#%d: %s' % (idx + 1, animal))
# Prints "#1: fish", "#2: dog", "#3: cat"

集合:像列表和字典一樣,我們可以用集合的理解來(lái)輕松地構(gòu)建集合:

from math import sqrt
nums = {int(sqrt(x)) for x in range(30)}
print(nums)  # Prints "{0, 1, 2, 3, 4, 5}"

元組
tuple是一個(gè)(不可變的)有序的值列表。元組在許多方面與列表相似;最重要的區(qū)別之一是,元組可以用作字典中的鍵,也可以作為集合的元素,而列表則不能。這里有一個(gè)簡(jiǎn)單的例子:

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"

方法/函數(shù)
Python函數(shù)是使用def關(guān)鍵字定義的。例如:

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"

我們通常會(huì)定義一些函數(shù)來(lái)選擇可選的關(guān)鍵字參數(shù),比如:

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中定義類的語(yǔ)法很簡(jiǎn)單:

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!"

Numpy

Numpy是Python中科學(xué)計(jì)算的核心庫(kù)。它提供了高性能多維數(shù)組對(duì)象和用于處理這些數(shù)組的工具。如果你已經(jīng)熟悉了MATLAB,你可能會(huì)發(fā)現(xiàn)這個(gè)教程很有用,可以從Numpy開始。

數(shù)組
numpy數(shù)組是一個(gè)值網(wǎng)格,所有類型都是相同類型的,并且被一個(gè)非負(fù)整數(shù)的元組索引。維數(shù)是數(shù)組的秩;數(shù)組的形狀是一個(gè)數(shù)組的數(shù)組,它在每個(gè)維度上給出數(shù)組的大小。
我們可以從嵌套的Python列表中初始化numpy數(shù)組,并使用方括號(hào)訪問元素:

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還提供了許多用于創(chuàng)建數(shù)組的函數(shù):

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]]"

您可以在文檔中閱讀關(guān)于數(shù)組創(chuàng)建的其他方法。

數(shù)組索引
Numpy提供了幾種索引數(shù)組的方法。
切片:類似于Python列表,可以將numpy數(shù)組切片。由于數(shù)組可能是多維的,所以您必須為數(shù)組的每個(gè)維度指定一個(gè)切片:

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"

您還可以將整型索引與片索引相混合。但是,這樣做會(huì)產(chǎn)生比原始數(shù)組更低級(jí)的數(shù)組。注意,這與MATLAB處理數(shù)組切片的方式有很大的不同:

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)"

整數(shù)數(shù)組索引:當(dāng)您使用分段索引到numpy數(shù)組時(shí),生成的數(shù)組視圖將始終是原始數(shù)組的子數(shù)組。相反,整數(shù)數(shù)組索引允許使用來(lái)自另一個(gè)數(shù)組的數(shù)據(jù)構(gòu)造任意的數(shù)組。這是一個(gè)例子:

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]"

整數(shù)數(shù)組索引的一個(gè)有用的技巧是在矩陣的每一行中選擇或變化(mutating )一個(gè)元素:

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]])

布爾數(shù)組索引:布爾數(shù)組索引可以讓你挑選出一個(gè)數(shù)組的任意元素。通常,這種類型的索引用于選擇滿足某些條件的數(shù)組的元素。這是一個(gè)例子:

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]"

為了簡(jiǎn)潔,我省略了很多關(guān)于numpy數(shù)組索引的細(xì)節(jié);如果你想知道更多,你應(yīng)該閱讀文檔。

數(shù)據(jù)類型
每個(gè)numpy數(shù)組都是相同類型的元素的網(wǎng)格。Numpy提供了一組大型的數(shù)字?jǐn)?shù)據(jù)類型,您可以使用它們來(lái)構(gòu)造數(shù)組。Numpy試圖在創(chuàng)建數(shù)組時(shí)猜測(cè)數(shù)據(jù)類型,但構(gòu)造數(shù)組的功能通常也包括一個(gè)可選的參數(shù),以顯式地指定數(shù)據(jù)類型。這是一個(gè)例子:

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"

您可以在文檔中閱讀所有關(guān)于numpy數(shù)據(jù)類型的信息。
矩陣運(yùn)算
基本的數(shù)學(xué)函數(shù)在數(shù)組上操作元素,并且可以作為操作符重載和在numpy模塊中的函數(shù):

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函數(shù)來(lái)計(jì)算向量的內(nèi)積,將一個(gè)向量乘以一個(gè)矩陣,再乘以矩陣。dot既可以作為numpy模塊中的函數(shù),也可以作為數(shù)組對(duì)象的實(shí)例方法:

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為在數(shù)組中執(zhí)行計(jì)算提供了許多有用的函數(shù);其中一個(gè)最有用的就是: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提供的數(shù)學(xué)函數(shù)的完整列表。

除了使用數(shù)組計(jì)算數(shù)學(xué)函數(shù)外,我們還經(jīng)常需要對(duì)數(shù)組中的數(shù)據(jù)進(jìn)行重構(gòu)或處理。這類操作最簡(jiǎn)單的例子就是轉(zhuǎn)置矩陣;要轉(zhuǎn)置矩陣,只需使用數(shù)組對(duì)象的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為操縱數(shù)組提供了更多的函數(shù);您可以在文檔中看到完整的列表。

廣播
廣播是一種強(qiáng)大的機(jī)制,它允許numpy在執(zhí)行算術(shù)運(yùn)算時(shí)使用不同形狀的數(shù)組。通常我們有一個(gè)更小的數(shù)組和一個(gè)更大的數(shù)組,我們希望使用較小的數(shù)組多次來(lái)對(duì)更大的數(shù)組執(zhí)行一些操作。
例如,假設(shè)我們想要在矩陣的每一行中添加一個(gè)常數(shù)向量。我們可以這樣做:

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)

然而,當(dāng)矩陣x非常大時(shí),在Python中計(jì)算一個(gè)顯式循環(huán)可能會(huì)比較慢。請(qǐng)注意,將向量v添加到矩陣x的每一行中,就相當(dāng)于將v垂直地堆疊起來(lái),從而形成一個(gè)矩陣vv,然后執(zhí)行x和vv的元素求和。我們可以這樣來(lái)實(shí)現(xiàn)這個(gè)方法:

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廣播允許我們?cè)诓粚?shí)際創(chuàng)建v的多個(gè)拷貝的情況下進(jìn)行計(jì)算,使用廣播:

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,)因?yàn)閺V播;這行代碼就像v實(shí)際上有形狀(4,3),每一行都是v的拷貝,并且求和是在元素上進(jìn)行的。

廣播兩個(gè)數(shù)組遵循以下規(guī)則:
1.如果數(shù)組沒有相同的秩,則在兩個(gè)形狀都有相同長(zhǎng)度的情況下,將較低級(jí)別數(shù)組的形狀提前結(jié)束。
2.如果兩個(gè)數(shù)組在維度中具有相同的大小,或者在維度中有一個(gè)數(shù)組的大小為1,那么這兩個(gè)數(shù)組在維度上是兼容的。
3.如果在所有維度上兼容,陣列就可以進(jìn)行廣播。
4.在廣播之后,每個(gè)陣列的表現(xiàn)就好像它的形狀等于兩個(gè)輸入陣列的元素最基本的形狀。
5.在任何維度中,一個(gè)數(shù)組的大小是1而另一個(gè)數(shù)組的大小大于1。

如果這種解釋沒有意義,請(qǐng)嘗試從文檔或解釋中閱讀解釋。
支持廣播的功能被稱為通用功能。您可以在文檔中找到所有通用函數(shù)的列表。

以下是一些廣播的應(yīng)用:

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)

廣播通常會(huì)使您的代碼更加簡(jiǎn)潔和快速,因此您應(yīng)該盡可能地使用它。

Numpy文檔
這個(gè)簡(jiǎn)短的概述涉及了許多您需要了解的關(guān)于numpy的重要內(nèi)容,但是還遠(yuǎn)遠(yuǎn)不夠。查看numpy引用,了解更多關(guān)于numpy的內(nèi)容。

SciPy
Numpy提供了一個(gè)高性能多維數(shù)組和基本工具來(lái)計(jì)算和操作這些數(shù)組。SciPy在此基礎(chǔ)上構(gòu)建,并提供了大量的函數(shù),這些函數(shù)可以在numpy數(shù)組中運(yùn)行,并且對(duì)于不同類型的科學(xué)和工程應(yīng)用程序非常有用。
熟悉SciPy的最好方法是瀏覽文檔

圖像操作
SciPy提供了一些基本功能來(lái)處理圖像。例如,它具有從磁盤讀取圖像到numpy數(shù)組的功能,將numpy數(shù)組寫入磁盤作為圖像,以及調(diào)整圖像大小。下面是一個(gè)展示這些功能的簡(jiǎn)單示例:

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)
圖片.png
圖片.png

點(diǎn)之間的距離
SciPy定義了一些有用的函數(shù),用于計(jì)算兩點(diǎn)之間的距離。
scipy.spatial.distance的函數(shù)。p主義者計(jì)算給定集合中所有的點(diǎn)之間的距離:

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)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容