Python3快速入門(十二)——NumPy

Python3快速入門(十二)——NumPy

一、NumPy簡介

1、NumPy簡介

NumPy(Numerical Python) 是 Python 語言的一個擴展程序庫,支持大量的維度數(shù)組與矩陣運算,同時對數(shù)組運算提供了大量的數(shù)學函數(shù)庫。
Numpy 是一個運行速度非常快的數(shù)學庫,內部解除了CPython的GIL,運行效率極好,主要用于數(shù)組計算,是大量機器學習框架的基礎庫,NumPy主要包括如下:
(1)強大的N維數(shù)組對象 ndarray
(2)廣播功能函數(shù)
(3)整合 C/C++/Fortran 代碼的工具
(4)線性代數(shù)、傅里葉變換、隨機數(shù)生成等功能。
NumPy 通常與?SciPy(Scientific Python)和?Matplotlib(繪圖庫)組合使用,用于替代 MatLab。

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:域名注冊、虛擬主機、營銷軟件、網站建設、金沙網站維護、網站推廣。

2、NumPy的優(yōu)缺點

NumPy優(yōu)點如下:
(1)對于同樣的數(shù)值計算任務,使用NumPy要比直接編寫Python代碼便捷得多。
(2)NumPy中的數(shù)組的存儲效率和輸入輸出性能均遠遠優(yōu)于Python中等價的基本數(shù)據結構,且其能夠提升的性能是與數(shù)組中的元素成比例的。
(3)NumPy的大部分代碼都用C語言寫,其底層算法在設計時有優(yōu)異的性能,使得NumPy比純Python代碼高效。
NumPy缺點如下:
由于NumPy使用內存映射文件以達到最優(yōu)的數(shù)據讀寫性能,而內存的大小限制了其對TB級大文件的處理;NumPy數(shù)組的通用性不及Python提供的list容器。

3、NumPy安裝

pip install --user numpy
--user 選項可以設置只安裝在當前的用戶下,而不是寫入到系統(tǒng)目錄。

4、NumPy數(shù)據類型

numpy支持的數(shù)據類型比 Python 內置的類型要多,基本上可以和 C 語言的數(shù)據類型對應上,其中部分類型對應為 Python 內置的類型。
bool_ 布爾型數(shù)據類型(True 或者 False)
int_ 默認的整數(shù)類型(類似于 C 語言中的 long,int32 或 int64)
intc 與 C 的 int 類型一樣,一般是 int32 或 int 64
intp 用于索引的整數(shù)類型(類似于 C 的 ssizet,通常是int32或 int64)
int8 字節(jié)(-128 to 127)
int16 整數(shù)(-32768 to 32767)
int32 整數(shù)(-2147483648 to 2147483647)
int64 整數(shù)(64bit)
uint8 無符號整數(shù)(0 to 255)
uint16 無符號整數(shù)(0 to 65535)
uint32 無符號整數(shù)(0 to 4294967295)
uint64 無符號整數(shù)(0 to 18446744073709551615)
`float
float64類型的簡寫<br/>float16 半精度浮點數(shù),包括:1 個符號位,5 個指數(shù)位,10 個尾數(shù)位<br/>float64 單精度浮點數(shù),包括:1 個符號位,8 個指數(shù)位,23 個尾數(shù)位<br/>float64 雙精度浮點數(shù),包括:1 個符號位,11 個指數(shù)位,52 個尾數(shù)位<br/>complex_` complex128類型的簡寫,即 128 位復數(shù)
complex64 復數(shù),表示雙 32 位浮點數(shù)(實數(shù)部分和虛數(shù)部分)
complex128 復數(shù),表示雙 64 位浮點數(shù)(實數(shù)部分和虛數(shù)部分)
每個內建類型都有一個唯一字符代碼:
b 布爾類型
i 有符號整型
u 無符號整型
f 浮點型
c 復數(shù)浮點型
m 時間間隔
M 日期間隔
O Python對象
S,a byte字符串
U Unicode
V 原始數(shù)據(void)

5、dtype數(shù)據類型對象

數(shù)據類型對象dtype用于描述與數(shù)組對應的內存區(qū)域如何使用,依賴如下幾個方面:
(1)數(shù)據的類型(整數(shù),浮點數(shù)或者 Python 對象)
(2)數(shù)據的大?。ɡ?, 整數(shù)使用多少個字節(jié)存儲)
(3)數(shù)據的字節(jié)順序(小端法或大端法)
(4)在結構化類型的情況下,字段的名稱、每個字段的數(shù)據類型和每個字段所取的內存塊的部分。
(5)如果數(shù)據類型是子數(shù)組,其形狀和數(shù)據類型。
(6)字節(jié)順序是通過對數(shù)據類型預先設定"<"或">"來決定的。"<"意味著小端法(最小值存儲在最小的地址,即低位組放在最前面)。">"意味著大端法(最重要的字節(jié)存儲在最小的地址,即高位組放在最前面)。
dtype 對象使用以下語法構造的:
numpy.dtype(object, align, copy)
object - 要轉換為的數(shù)據類型對象
align - 如果為 true,填充字段使其類似 C 的結構體。
copy - 復制 dtype 對象 ,如果為 false,則是對內置數(shù)據類型對象的引用
一個結構化數(shù)據類型 student,包含字符串字段 name,整數(shù)字段 age,及浮點字段 score,并將 dtype 應用到 ndarray 對象。

import numpy

if __name__ == "__main__":
    student = numpy.dtype([("name", "S20"), ("age", numpy.int8), ("marks", "<f4")])
    student_array = numpy.array([("Bauer", 22, 88), ("Jack", 21, 90), ("Alex", 78, 22)], dtype=student)
    print(student_array)

# output:
# [(b'Bauer', 22, 88.) (b'Jack', 21, 90.) (b'Alex', 78, 22.)]

二、ndarray

1、ndarray簡介

ndarray是NumPy的核心,ndarray封裝了python原生的同數(shù)據類型的n維數(shù)組,通過正整數(shù)元組索引。
ndarray內部結構如下:
(1)一個指向數(shù)據(內存或內存映射文件中的一塊數(shù)據)的指針。
(2)數(shù)據類型(dtype),描述在數(shù)組中的固定大小值的格子。
(3)一個表示數(shù)組形狀(shape)的元組,表示各維度大小的元組。
(4)一個跨度元組(stride),其中整數(shù)指的是為了前進到當前維度下一個元素需要"跨過"的字節(jié)數(shù)。
Python3快速入門(十二)——NumPy
ndarray 和 標準Python 數(shù)組的區(qū)別如下:
(1)ndarray 在創(chuàng)建時具有固定的大小, 更改ndarray的大小將創(chuàng)建一個新數(shù)組并刪除原來的數(shù)組,與Python的原生數(shù)組對象(可以動態(tài)增長)不同。
(2)ndarray 中的元素必須具有相同的數(shù)據類型,因此在內存中的大小相同。
(3)ndarray 有助于對大量數(shù)據進行高級數(shù)學和其它類型的操作。 通常,ndarray 的執(zhí)行效率更高,比使用Python原生數(shù)組的代碼更少。
(4)大部分基于Python的科學和數(shù)學軟件包都使用NumPy數(shù)組,盡管通常也支持Python原生數(shù)組作為參數(shù),但在處理前仍然會將輸入數(shù)組轉換為NumPy數(shù)組,而且通常輸出為NumPy數(shù)組。為了高效地使用當今基于Python的科學計算工具,需要知道如何使用NumPy數(shù)組。

2、ndarray?對象的屬性

ndarray?對象提供的關鍵屬性如下:
ndarray.ndim:數(shù)組的軸(維度)的個數(shù),維度的數(shù)量被稱為rank。
ndarray.shape:數(shù)組的維度,是一個整數(shù)的元組,表示每個維度中數(shù)組的大小。對于n行和m列的矩陣,shape是(n,m)。因此,shape元組的長度就是rank或維度的個數(shù)?ndim。
ndarray.size:數(shù)組元素的總數(shù),等于shape的元素的乘積。
ndarray.dtype:描述數(shù)組中元素類型的對象??梢允褂脴藴实腜ython類型創(chuàng)建或指定dtype。NumPy提供自己的類型,如numpy.int32、numpy.int16和numpy.float64。
ndarray.itemsize:數(shù)組中每個元素的字節(jié)大小,等于?ndarray.dtype.itemsize。元素為?float64?類型的數(shù)組的?itemsize?為8(=64/8),而?complex32?類型的數(shù)組的?itemsize?為4(=32/8)。
ndarray.flags:ndarray對象的內存信息。
ndarray.real:ndarray元素的實部
ndarray.imag:ndarray 元素的虛部
ndarray.data:緩沖區(qū)包含數(shù)組的實際元素。
Ndarray.flags的內存信息屬性如下:
C_CONTIGUOUS (C):數(shù)據是在一個單一的C風格的連續(xù)段中
F_CONTIGUOUS (F):數(shù)據是在一個單一的Fortran風格的連續(xù)段中
OWNDATA (O):數(shù)組擁有自己所使用的內存或從另一個對象中借用
WRITEABLE (W:)數(shù)據區(qū)域可以被寫入,將值設置為 False,則數(shù)據為只讀。
ALIGNED (A):數(shù)據和所有元素都適當?shù)貙R到硬件上。
UPDATEIFCOPY (U):數(shù)組是其它數(shù)組的一個副本,當數(shù)組被釋放時,原數(shù)組的內容將被更新。

import numpy

if __name__ == "__main__":
    a = numpy.arange(15).reshape(5, 3)
    print(a)
    print("shape: ", a.shape)
    print("ndim:", a.ndim)
    print("dtype:", a.dtype.name)
    print("itemsize: ", a.itemsize)
    print("itemsize: ", a.dtype.itemsize)
    print("size: ", a.size)
    print("flags: ", a.flags)
    print("data: ", a.data)
    print("type:", type(a))

# output:
# [[ 0  1  2]
#  [ 3  4  5]
#  [ 6  7  8]
#  [ 9 10 11]
#  [12 13 14]]
# shape:  (5, 3)
# ndim: 2
# dtype: int64
# itemsize:  8
# itemsize:  8
# size:  15
# flags:    C_CONTIGUOUS : True
#   F_CONTIGUOUS : False
#   OWNDATA : False
#   WRITEABLE : True
#   ALIGNED : True
#   WRITEBACKIFCOPY : False
#   UPDATEIFCOPY : False
# data:  <memory at 0x7f1b6fbf4b40>
# type: <class 'numpy.ndarray'>

3、創(chuàng)建數(shù)組

numpy.empty(shape, dtype = float, order = 'C')
numpy.empty 方法用來創(chuàng)建一個指定形狀(shape)、數(shù)據類型(dtype)且未初始化的數(shù)組。

import numpy

if __name__ == "__main__":
    array_empty = numpy.empty([2, 3])
    print(array_empty)

# output:
# [[6.92184835e-310 1.23016891e-316 6.92184893e-310]
#  [6.92184893e-310 1.45897537e-303 2.72466824e-311]]

numpy.array(p_object, dtype=None, copy=True, order='K', subok=False, ndmin=0)
創(chuàng)建數(shù)組,p_object為數(shù)組或序列,dtype為數(shù)組元素類型

import numpy

if __name__ == "__main__":
    a = numpy.array([[1, 2, 3], [4, 5, 6]], numpy.int)
    print(a)
# output:
# [[1 2 3]
#  [4 5 6]]

numpy.asarray(a, dtype = None, order = None)
創(chuàng)建數(shù)組,a為數(shù)組或序列,dtype為數(shù)組元素類型

import numpy

if __name__ == "__main__":
    array_as = numpy.asarray([[1, 2, 3, 4], [5, 6, 7, 8]])
    print(array_as)

# output:
# [[1 2 3 4]
#  [5 6 7 8]]

numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
numpy.frombuffer 用于實現(xiàn)動態(tài)數(shù)組。
buffer 參數(shù)為人以對象,以流的形式讀入轉化成 ndarray 對象。buffer 是字符串的時候,Python3 默認 str 是 Unicode 類型,所以要轉成 bytestring 在原 str 前加上 b。
dtype參數(shù),數(shù)組的數(shù)據類型,可選。
count參數(shù),讀取的數(shù)據量,默認為-1,讀取所有的數(shù)據。
offset參數(shù),讀取的起始位置,默認為0。

import numpy

if __name__ == "__main__":
    s = b"Hello, Python"
    a = numpy.frombuffer(s, dtype="S1")
    print(a)

# output:
# [b'H' b'e' b'l' b'l' b'o' b',' b' ' b'P' b'y' b't' b'h' b'o' b'n']

numpy.fromiter(iterable, dtype, count=-1)
numpy.fromiter 方法從可迭代對象中建立 ndarray 對象,返回一維數(shù)組。
Iterable參數(shù),可迭代對象。
dtype參數(shù),數(shù)組的數(shù)據類型,可選。
count參數(shù),讀取的數(shù)據數(shù)量,默認為-1,讀取所有數(shù)據。

import numpy

if __name__ == "__main__":
    # 使用 range 函數(shù)創(chuàng)建列表對象
    l = range(10)
    it = iter(l)
    # 使用迭代器創(chuàng)建 ndarray
    x = numpy.fromiter(it, dtype=float)
    print(x)

# output:
# [0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]

numpy.ones(shape, dtype=None, order='C')
創(chuàng)建數(shù)值為1的數(shù)組,shape是數(shù)組的形狀,dtype是數(shù)值類型。

import numpy

if __name__ == "__main__":
    array_ones = numpy.ones((2, 3), numpy.int)
    print(array_ones)
# output:
# [[1 1 1]
#  [1 1 1]]

numpy.zeros(shape, dtype=None, order='C')
創(chuàng)建數(shù)值為0的數(shù)組,shape是數(shù)組的形狀,dtype是數(shù)值類型。

import numpy

if __name__ == "__main__":
    array_zeros = numpy.zeros((2, 3), numpy.int)
    print(array_zeros)
# output:
# [[0 0 0]
#  [0 0 0]]

numpy.full(shape, fill_value, dtype=None, order='C')
創(chuàng)建指定數(shù)值的數(shù)組,shape是數(shù)組的形狀,fill_value是數(shù)值,dtype是數(shù)值類型。

import numpy

if __name__ == "__main__":
    array_full = numpy.full((2, 3), 3.14, numpy.float)
    print(array_full)
# output:
# [[3.14 3.14 3.14]
#  [3.14 3.14 3.14]]

numpy.eye(N, M=None, k=0, dtype=float, order='C')
創(chuàng)建單位矩陣,N為行數(shù),M為列數(shù)

import numpy

if __name__ == "__main__":
    array_eye = numpy.eye(2, 3)
    print(array_eye)
# output:
# [[1. 0. 0.]
#  [0. 1. 0.]]

numpy.diag(v, k=0)
創(chuàng)建對角矩陣,v是主對角線數(shù)值,k是對角線元素,k = 0表示主對角線,k>0的值選擇在主對角線之上的對角線中的元素,k&lt;0的值選擇在主對角線之下的對角線中的元素。

import numpy

if __name__ == "__main__":
    array_diag = numpy.diag([1, 2, 3], k=1)
    print(array_diag)
# output:
# [[0 1 0 0]
#  [0 0 2 0]
#  [0 0 0 3]
#  [0 0 0 0]]

numpy.random.rand(*dn)
創(chuàng)建指定shape的數(shù)組,數(shù)值范圍在0~1之間。dn是可變參數(shù),接收多個參數(shù)用于指定數(shù)組的shape。

import numpy

if __name__ == "__main__":
    array_rand = numpy.random.rand(2, 3)
    print(array_rand)
# output:
# [[0.73299266 0.10939252 0.61875294]
#  [0.11556114 0.62150992 0.56455656]]

numpy.random.uniform(low=0.0, high=1.0, size=None)
創(chuàng)建指定范圍內的數(shù)值的數(shù)或數(shù)組,low為下限,high為上限,size為個數(shù),可以為序列,用于指定數(shù)組的shape。

import numpy

if __name__ == "__main__":
    array_uniform = numpy.random.uniform(3, 3.14, (2, 3))
    print(array_uniform)
    print(numpy.random.uniform(0, 100, 3))
# output:
# [[3.00724161 3.10009725 3.04795313]
#  [3.06319773 3.12678593 3.09834495]]
# [73.03084565 34.16123519 95.58874675]

numpy.randint(low, high=None, size=None, dtype='l')
創(chuàng)建指定范圍內的數(shù)值的數(shù)或數(shù)組,low為下限,high為上限,size為個數(shù),可以為序列,用于指定數(shù)組的shape。

import numpy

if __name__ == "__main__":
    array_randint = numpy.random.randint(0, 10, (2, 3), dtype=numpy.int)
    print(array_randint)
    print(numpy.random.randint(0, 100, 3, dtype=numpy.int))

# output:
# [[6 2 8]
#  [1 4 8]]
# [60 16 25]

numpy.arange(start=None, *args, **kwargs)
創(chuàng)建一維數(shù)組,其中包含位于半開區(qū)間[start, stop)內并均勻分布的值,step表示步長。

import numpy

if __name__ == "__main__":
    array_arange = numpy.arange(0, 10, 3)
    print(array_arange)

# output:
# [0 3 6 9]

numpy.linspace(start, stop, N)
創(chuàng)建N個在閉區(qū)間[start, stop]內均勻分布的值。

import numpy

if __name__ == "__main__":
    array_linspace = numpy.linspace(0, 10, 5)
    print(array_linspace)

# output:
# [ 0.   2.5  5.   7.5 10. ]

numpy.random.normal(loc=0.0, scale=1.0, size=None)
創(chuàng)建給定均值loc、標準差scale、維度size的正態(tài)分布

import numpy

if __name__ == "__main__":
    array_normal = numpy.random.normal(loc=1.75, scale=0.1, size=[2, 3])
    print(array_normal)

# output:
# [[1.6629973  1.78608724 1.83688018]
#  [1.77781707 1.62255632 1.73506316]]

4、ndarray索引

ndarray對象的內容可以通過索引或切片來訪問和修改,與 Python 中 list 的切片操作一樣。
ndarray 數(shù)組可以基于 0 - n 的下標進行索引,切片對象可以通過內置的 slice 函數(shù),并設置 start, stop 及 step 參數(shù)進行,從原數(shù)組中切割出一個新數(shù)組。
array[start : end:step]:截取start到end的切片,間隔為step
array[start:]:截取從start到結尾的切片
array[:end]:截取從開始到end的切片

import numpy

if __name__ == "__main__":
    array_rand = numpy.arange(1, 10)
    print(array_rand)
    print(array_rand[1:7:2])

# output:
# [1 2 3 4 5 6 7 8 9]
# [2 4 6]

ndarray數(shù)組可以通過整數(shù)數(shù)組進行索引,通常需要分別構造行索引和列索引的數(shù)組,通過行索引數(shù)組和列索引數(shù)組組合使用最終定位數(shù)組的索引。

import numpy

if __name__ == "__main__":
    array_rand = numpy.random.randint(0, 10, [5, 8])
    print(array_rand)
    rows = numpy.array([[0, 0], [3, 3]])
    cols = numpy.array([[0, 2], [0, 2]])
    result = array_rand[rows, cols]
    print(result)

# output:
# [[6 1 7 7 6 1 0 5]
#  [9 5 4 6 1 0 8 0]
#  [0 2 1 5 3 3 5 6]
#  [4 4 5 0 2 5 2 2]
#  [1 9 8 5 7 1 3 2]]
# [[6 7]
#  [4 5]]

ndarray可以通過一個布爾數(shù)組來進行索,布爾索引通過布爾運算(如:比較運算符)來獲取符合指定條件的元素的數(shù)組。

import numpy

if __name__ == "__main__":
    array_rand = numpy.random.randint(0, 10, [5, 8])
    print(array_rand)
    result = array_rand[array_rand > 5]
    print(result)

# output:
# [[2 3 2 2 0 5 4 7]
#  [8 8 2 8 6 5 9 7]
#  [9 6 3 9 5 9 9 5]
#  [3 9 1 1 8 7 9 7]
#  [8 2 0 6 5 0 2 7]]
# [7 8 8 8 6 9 7 9 6 9 9 9 9 8 7 9 7 8 6 7]

5、數(shù)組修改

numpy.ndarray.reshape(a, newshape, order='C')
把指定的數(shù)組改變形狀,但元素個數(shù)不變;有返回值,即不對原始多維數(shù)組進行修改。a是數(shù)組,newshape為新的shape。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, 10)
    b = numpy.reshape(a, [2, 5])
    print(a)
    print(b)
    c = b.reshape([1, 10])
    print(b)
    print(c)

# output:
# [2 7 0 7 3 0 3 2 5 2]
# [[2 7 0 7 3]
#  [0 3 2 5 2]]
# [[2 7 0 7 3]
#  [0 3 2 5 2]]
# [[2 7 0 7 3 0 3 2 5 2]]

numpy.ndarray.resize(a, new_shape)
把指定的數(shù)組改變形狀,但元素個數(shù)可變,不足補0。numpy.resize作為含磺素使用時,不會對原始數(shù)組進行修改,返回新的結果數(shù)組;array.resize作為方法使用時,無返回值,會對原始多維數(shù)組進行修改。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, 10)
    print(a)
    # 不修改原始數(shù)組
    b = numpy.resize(a, [3, 4])
    print(a)
    print(b)
    # 修改原始數(shù)組
    a.resize([3, 4])
    print(a)

# output:
# [0 0 7 5 7 1 3 8 1 9]
# [0 0 7 5 7 1 3 8 1 9]
# [[0 0 7 5]
#  [7 1 3 8]
#  [1 9 0 0]]
# [[0 0 7 5]
#  [7 1 3 8]
#  [1 9 0 0]]

三、NumPy 數(shù)組迭代

1、迭代數(shù)組簡介

NumPy 迭代器對象 numpy.nditer 提供了一種靈活訪問一個或者多個數(shù)組元素的方式。

import numpy

if __name__ == "__main__":
    a = numpy.arange(0, 12).reshape([2, 6])
    print(a)
    it = numpy.nditer(a)
    for x in it:
        print(x, end=", ")
    print("\n")
    for x in numpy.nditer(a.T.copy(order='C')):
        print(x, end=", ")

# output:
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]]
# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
#
# 0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11,

2、遍歷順序控制

for x in numpy.nditer(arr, order='F'):
    pass

for x in numpy.nditer(arr.T, order='C'):
    pass

order='F',表示Fortran order,即列序優(yōu)先;order='C',表示C order,即行序優(yōu)先。

3、遍歷修改數(shù)組元素值

nditer 對象有一個可選參數(shù) op_flags。 默認情況下,nditer將視待迭代遍歷的數(shù)組為只讀對象(read-only),為了在遍歷數(shù)組的同時,實現(xiàn)對數(shù)組元素值得修改,必須指定 read-write 或者 write-only 的模式。

import numpy

if __name__ == "__main__":
    a = numpy.arange(0, 12).reshape([2, 6])
    print(a)
    it = numpy.nditer(a, op_flags=["readwrite"])
    for x in it:
        x[...] = x**2
    print(a)

# output:
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]]
# [[  0   1   4   9  16  25]
#  [ 36  49  64  81 100 121]]

4、外部循環(huán)

nditer的構造器擁有flags參數(shù),可以接受下列值:
c_index:可以跟蹤 C 順序的索引
f_index:可以跟蹤 Fortran 順序的索引
multi-index:每次迭代可以跟蹤一種索引類型
external_loop:給出的值是具有多個值的一維數(shù)組,而不是零維數(shù)組

5、廣播迭代

如果兩個數(shù)組是可廣播的,nditer 組合對象能夠同時迭代。 假設數(shù)組 a 的維度為 3X4,數(shù)組 b 的維度為 1X4 ,則使用迭代器(數(shù)組 b 被廣播到 a 的大?。┤缦拢?/p>

import numpy

if __name__ == "__main__":
    a = numpy.arange(0, 12).reshape([3, 4])
    print(a)
    b = [11, 12, 13, 14]
    it = numpy.nditer([a, b])
    for x, y in it:
        print("%d:%d" % (x, y), end=", ")

# output:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
# 0:11, 1:12, 2:13, 3:14, 4:11, 5:12, 6:13, 7:14, 8:11, 9:12, 10:13, 11:14,

四、NumPy運算

1、條件運算

numpy.where(condition, x=None, y=None)
三目運算,滿足condition,為x;不滿足condition,則為y。返回新的結果數(shù)組。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, 10)
    print(a)
    b = numpy.where(a < 5, 5, 0)
    print(b)

# output:
# [8 9 6 5 3 2 9 7 3 4]
# [0 0 0 0 5 5 0 0 5 5]

2、統(tǒng)計函數(shù)

numpy.amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue)
根據指定軸統(tǒng)計矩陣的最大值,axis=0統(tǒng)計矩陣中每一列的最大值,axis=1統(tǒng)計矩陣中每一行的最大值,默認統(tǒng)計矩陣中的最大值。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 100, [3, 5])
    print(a)
    # 統(tǒng)計整個矩陣的最大值
    result = numpy.amax(a)
    print(result)
    # 統(tǒng)計矩陣中每一列的最大值
    result = numpy.amax(a, axis=0)
    print(result)
    # 統(tǒng)計矩陣中每一行的最大值
    result = numpy.amax(a, axis=1)
    print(result)

# output:
# [[85 54 46 38 98]
#  [27 65 23 13 63]
#  [43 68 31 42 82]]
# 98
# [85 68 46 42 98]
# [98 65 82]

numpy.amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue)
根據指定軸統(tǒng)計矩陣的最小值,axis=0統(tǒng)計矩陣中每一列的最小值,axis=1統(tǒng)計矩陣中每一行的最小值,默認統(tǒng)計矩陣中的最小值。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 100, [3, 5])
    print(a)
    # 統(tǒng)計整個矩陣的最小值
    result = numpy.amin(a)
    print(result)
    # 統(tǒng)計矩陣中每一列的最小值
    result = numpy.amin(a, axis=0)
    print(result)
    # 統(tǒng)計矩陣中每一行的最小值
    result = numpy.amin(a, axis=1)
    print(result)

# output:
# [[74 95 64 18 99]
#  [24 61 36  2 65]
#  [66 68  9 19 19]]
# 2
# [24 61  9  2 19]
# [18  2  9]

numpy.mean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue)
根據指定軸統(tǒng)計矩陣的平均值,axis=0統(tǒng)計矩陣中每一列的平均值,axis=1統(tǒng)計矩陣中每一行的平均值,默認統(tǒng)計矩陣中的平均值。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 100, [3, 5])
    print(a)
    # 統(tǒng)計整個矩陣的平均值
    result = numpy.mean(a)
    print(result)
    # 統(tǒng)計矩陣中每一列的平均值
    result = numpy.mean(a, axis=0)
    print(result)
    # 統(tǒng)計矩陣中每一行的平均值
    result = numpy.mean(a, axis=1)
    print(result)

# output:
# [[38 36 68 78 58]
#  [41 38 84 92 95]
#  [52 86 62 94 33]]
# 63.666666666666664
# [43.66666667 53.33333333 71.33333333 88.         62.        ]
# [55.6 70.  65.4]

numpy.std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue)
根據指定軸統(tǒng)計矩陣的方差,axis=0統(tǒng)計矩陣中每一列的方差,axis=1統(tǒng)計矩陣中每一行的方差,默認統(tǒng)計矩陣中的方差。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 100, [3, 5])
    print(a)
    # 統(tǒng)計整個矩陣的方差
    result = numpy.std(a)
    print(result)
    # 統(tǒng)計矩陣中每一列的方差
    result = numpy.std(a, axis=0)
    print(result)
    # 統(tǒng)計矩陣中每一行的方差
    result = numpy.std(a, axis=1)
    print(result)

# output:
# [[80 68 47 51  2]
#  [75 38 97 70 98]
#  [57 66 64 17 70]]
# 25.442746183015178
# [ 9.87702159 13.69509239 20.7578633  21.92411154 40.30991055]
# [26.59774427 21.9326241  19.36388391]

numpy.sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._NoValue)
根據指定軸統(tǒng)計矩陣的求和,axis=0統(tǒng)計矩陣中每一列的求和,axis=1統(tǒng)計矩陣中每一行的求和,默認統(tǒng)計矩陣中的求和。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 100, [3, 5])
    print(a)
    # 統(tǒng)計整個矩陣的求和
    result = numpy.sum(a)
    print(result)
    # 統(tǒng)計矩陣中每一列的求和
    result = numpy.sum(a, axis=0)
    print(result)
    # 統(tǒng)計矩陣中每一行的求和
    result = numpy.sum(a, axis=1)
    print(result)

# output:
# [[87 16 90 96 83]
#  [23 96 52 76 39]
#  [46  5 55 91 66]]
# 921
# [156 117 197 263 188]
# [372 286 263]

numpy.ptp()()ptp(a, axis=None, out=None, keepdims=np._NoValue)
計算數(shù)組中元素最大值與最小值的差(最大值 - 最小值)

numpy.percentile(a, q, axis=None, out=None,
               overwrite_input=False, interpolation='linear', keepdims=False)

百分位數(shù)是統(tǒng)計中使用的度量,表示小于這個值的觀察值的百分比
參數(shù)a,輸入數(shù)組
參數(shù)q,要計算的百分位數(shù),在 0 ~ 100 之間
參數(shù)axis: 沿著計算百分位數(shù)的軸
numpy.median(a, axis=None, out=None, overwrite_input=False, keepdims=False)
用于計算數(shù)組 a 中元素的中位數(shù)(中值)
numpy.average(a, axis=None, weights=None, returned=False)
根據各自的權重計算數(shù)組中元素的加權平均值。
參數(shù)a,輸入數(shù)組
參數(shù)axis,指定軸
weights:權重

import numpy

if __name__ == "__main__":
    a = numpy.array([10, 20, 30, 40])
    print(numpy.average(a))
    weight = [1, 2, 3, 4]
    result = numpy.average(a, weights=weight)
    print(result)
    result = numpy.average(a, weights=weight, returned=True)
    print(result)

# output:
# 25.0
# 30.0
# (30.0, 10.0)

3、算術運算

數(shù)組與數(shù)的運算包括加、減、乘、除、取整、取模,可以使用函數(shù)也可以使用操作符。
numpy.add(x1, x2, *args, **kwargs)
將x1和x2相加,并將結果返回。
numpy.subtract(x1, x2, *args, **kwargs)
將x1和x2相減,并將結果返回。
numpy.multiply(x1, x2, *args, **kwargs)
將x1和x2相乘,并將結果返回。
numpy.divide(x1, x2, *args, **kwargs)
將x1和x2相除,并將結果返回。
numpy.mod(*args, **kwargs)
計算輸入數(shù)組中相應元素的相除后的余數(shù)
numpy.power(x1, x2, *args, **kwargs)
將x1作為底數(shù),計算x1的x2次冪。
numpy.reciprocal(x, *args, **kwargs)
返回x的倒數(shù)。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, [2, 5])
    print(a)
    result = a + 5
    print(result)
    result = a - 5
    print(result)
    result = a * 5
    print(result)
    result = a / 5
    print(result)
    result = a // 5
    print(result)
    result = a % 5
    print(result)

# output:
# [[9 6 6 7 9]
#  [0 3 2 4 8]]
# [[14 11 11 12 14]
#  [ 5  8  7  9 13]]
# [[ 4  1  1  2  4]
#  [-5 -2 -3 -1  3]]
# [[45 30 30 35 45]
#  [ 0 15 10 20 40]]
# [[1.8 1.2 1.2 1.4 1.8]
#  [0.  0.6 0.4 0.8 1.6]]
# [[1 1 1 1 1]
#  [0 0 0 0 1]]
# [[4 1 1 2 4]
#  [0 3 2 4 3]]

數(shù)組間運算包括加、減、乘、除,但兩個數(shù)組的shape必須一樣。
numpy.intersect1d(ar1, ar2, assume_unique=False, return_indices=False)
查找兩個數(shù)組中的相同元素。
numpy.setdiff1d(ar1, ar2, assume_unique=False)
查找在數(shù)組a中不在數(shù)組b中的元素。
numpy.union1d(ar1, ar2)
查找兩個數(shù)組的并集元素

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(1, 10, [2, 5])
    b = numpy.random.randint(1, 10, [2, 5])
    print(a)
    print(b)
    result = a + b
    print(result)
    result = a - b
    print(result)
    result = a * b
    print(result)
    result = a / b
    print(result)
    # 求交
    result = numpy.intersect1d(a, b)
    print(result)
    # 求差
    result = numpy.setdiff1d(a, b)
    print(result)
    # 求并
    result = numpy.union1d(a, b)
    print(result)

# output:
# [[2 8 4 1 5]
#  [1 9 4 4 7]]
# [[9 2 4 7 3]
#  [7 7 3 2 1]]
# [[11 10  8  8  8]
#  [ 8 16  7  6  8]]
# [[-7  6  0 -6  2]
#  [-6  2  1  2  6]]
# [[18 16 16  7 15]
#  [ 7 63 12  8  7]]
# [[0.22222222 4.         1.         0.14285714 1.66666667]
#  [0.14285714 1.28571429 1.33333333 2.         7.        ]]
# [1 2 4 7 9]
# [5 8]
# [1 2 3 4 5 7 8 9]

4、廣播

廣播(Broadcast)是 numpy 對不同shape的數(shù)組進行數(shù)值計算的方式, 對數(shù)組的算術運算通常在相應的元素上進行。
如果兩個數(shù)組進行運算時必須要求shape相同,當運算中的 2 個數(shù)組的shape不同時,numpy 將自動觸發(fā)廣播機制。
廣播機制的規(guī)則如下:
(1)讓所有輸入數(shù)組都向其中形狀最長的數(shù)組看齊,形狀中不足的部分都通過在前面加 1 補齊。
(2)輸出數(shù)組的形狀是輸入數(shù)組形狀的各個維度上的最大值。
(3)如果輸入數(shù)組的某個維度和輸出數(shù)組的對應維度的長度相同或者其長度為 1 時,這個數(shù)組能夠用來計算,否則出錯。
(4)當輸入數(shù)組的某個維度的長度為 1 時,沿著此維度運算時都用此維度上的第一組值。
如果條件不滿足,拋出?"ValueError: frames are not aligned"?異常。
4x3 的二維數(shù)組與1x 3 的一維數(shù)組相加,等效于把一維數(shù)組 在二維上重復 4 次再運算。
Python3快速入門(十二)——NumPy

import numpy

if __name__ == "__main__":
    a = numpy.array([[0, 0, 0],
                  [10, 10, 10],
                  [20, 20, 20],
                  [30, 30, 30]])
    b = numpy.array([1, 2, 3])
    result = a + b
    print(result)

# output:
# [[ 1  2  3]
#  [11 12 13]
#  [21 22 23]
#  [31 32 33]]

5、矩陣運算

numpy.dot(a, b, out=None)
矩陣點乘,(M行,N列)*(N行,Z列)=(M行,Z列)

import numpy

if __name__ == "__main__":
    # 成績,期末考試成績和平常作業(yè)成績組成
    score = numpy.array([[100, 87], [88, 87], [78, 80], [65, 89]])
    # 權重因子,期末成績占70%,平時作業(yè)成績占30%
    q = numpy.array([[0.7], [0.3]])
    result = numpy.dot(score, q)
    print(result)

# output:
# [[96.1]
#  [87.7]
#  [78.6]
#  [72.2]]

numpy.vstack(tup)
矩陣垂直拼接(兩個矩陣列數(shù)必須相同,行數(shù)隨意),參數(shù)tup為數(shù)組的元組。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, [3, 6])
    b = numpy.random.randint(0, 10, [2, 6])
    print(a)
    print(b)
    result = numpy.vstack((a, b))
    print(result)

# output:
# [[2 5 7 6 2 8]
#  [1 7 2 2 0 0]
#  [1 1 5 8 3 4]]
# [[6 5 3 4 9 9]
#  [4 3 2 4 2 9]]
# [[2 5 7 6 2 8]
#  [1 7 2 2 0 0]
#  [1 1 5 8 3 4]
#  [6 5 3 4 9 9]
#  [4 3 2 4 2 9]]

numpy.hstack(tup)
矩陣水平拼接(兩個矩陣行數(shù)必須相同,列數(shù)隨意),參數(shù)tup為數(shù)組的元組。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, [2, 3])
    b = numpy.random.randint(0, 10, [2, 4])
    c = numpy.random.randint(0, 10, [2, 5])
    print(a)
    print(b)
    print(c)
    result = numpy.hstack((a, b, c))
    print(result)

# output:
# [[5 4 2]
#  [3 3 3]]
# [[7 0 7 7]
#  [3 5 0 2]]
# [[8 6 3 0 2]
#  [3 9 7 4 1]]
# [[5 4 2 7 0 7 7 8 6 3 0 2]
#  [3 3 3 3 5 0 2 3 9 7 4 1]]

numpy.delete(arr, obj, axis=None)
矩陣刪除,參數(shù)arr為數(shù)組;參數(shù)obj為要刪除的對象;參數(shù)axis為軸,axis=0表示刪除行,axis=1表示刪除列,默認刪除行和列。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, [10, 10])
    print(a)
    result = numpy.delete(a, [0, 2])
    print(result)
    result = numpy.delete(a, [0, 2], axis=0)
    print(result)
    result = numpy.delete(a, [0, 2], axis=1)
    print(result)

# output:
# [[8 0 7 2 1 6 8 9 5 5]
#  [6 3 1 6 5 5 5 6 1 8]
#  [2 0 8 5 0 2 4 7 6 3]
#  [8 8 3 9 3 1 9 6 4 2]
#  [2 1 5 1 2 9 9 5 9 9]
#  [2 2 8 1 5 8 6 7 2 9]
#  [9 6 2 7 6 0 1 5 1 8]
#  [7 9 8 7 8 6 8 5 1 6]
#  [1 9 6 9 4 1 7 7 0 9]
#  [7 1 8 8 7 1 0 2 7 2]]
# [0 2 1 6 8 9 5 5 6 3 1 6 5 5 5 6 1 8 2 0 8 5 0 2 4 7 6 3 8 8 3 9 3 1 9 6 4
#  2 2 1 5 1 2 9 9 5 9 9 2 2 8 1 5 8 6 7 2 9 9 6 2 7 6 0 1 5 1 8 7 9 8 7 8 6
#  8 5 1 6 1 9 6 9 4 1 7 7 0 9 7 1 8 8 7 1 0 2 7 2]
# [[6 3 1 6 5 5 5 6 1 8]
#  [8 8 3 9 3 1 9 6 4 2]
#  [2 1 5 1 2 9 9 5 9 9]
#  [2 2 8 1 5 8 6 7 2 9]
#  [9 6 2 7 6 0 1 5 1 8]
#  [7 9 8 7 8 6 8 5 1 6]
#  [1 9 6 9 4 1 7 7 0 9]
#  [7 1 8 8 7 1 0 2 7 2]]
# [[0 2 1 6 8 9 5 5]
#  [3 6 5 5 5 6 1 8]
#  [0 5 0 2 4 7 6 3]
#  [8 9 3 1 9 6 4 2]
#  [1 1 2 9 9 5 9 9]
#  [2 1 5 8 6 7 2 9]
#  [6 7 6 0 1 5 1 8]
#  [9 7 8 6 8 5 1 6]
#  [9 9 4 1 7 7 0 9]
#  [1 8 7 1 0 2 7 2]]

numpy.append(arr, values, axis=None)
矩陣添加,參數(shù)arr為數(shù)組;參數(shù)values為要追加的對象;參數(shù)axis為軸,axis=0表示追加到行,axis=1表示追加到列,默認添加到所有數(shù)組元素的尾部。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, [3, 8])
    print(a)
    result = numpy.append(a, [0, 2, 3])
    print(result)
    # 追加一行
    result = numpy.append(a, [[9, 9, 9, 9, 9, 9, 9, 9]], axis=0)
    print(result)
    # 追加一列
    result = numpy.append(a, [[9], [9], [9]], axis=1)
    print(result)

# output:
# [[3 0 2 8 1 2 2 6]
#  [4 2 5 7 3 4 6 9]
#  [3 3 2 6 2 7 9 9]]
# [3 0 2 8 1 2 2 6 4 2 5 7 3 4 6 9 3 3 2 6 2 7 9 9 0 2 3]
# [[3 0 2 8 1 2 2 6]
#  [4 2 5 7 3 4 6 9]
#  [3 3 2 6 2 7 9 9]
#  [9 9 9 9 9 9 9 9]]
# [[3 0 2 8 1 2 2 6 9]
#  [4 2 5 7 3 4 6 9 9]
#  [3 3 2 6 2 7 9 9 9]]

numpy.insert(arr, obj, values, axis=None)
矩陣插入,參數(shù)arr為數(shù)組,obj為插入位置索引,values為插入的值,參數(shù)axis為軸,axis=0表示插入到行,axis=1表示插入到列,默認插入到所有數(shù)組元素的序列的指定位置。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, [3, 8])
    print(a)
    result = numpy.insert(a, 0, [11, 12, 13])
    print(result)
    result = numpy.insert(a, 0, [11, 12, 13, 14, 15, 16, 17, 18], axis=0)
    print(result)
    result = numpy.insert(a, 0, [11, 12, 13], axis=1)
    print(result)

# output:
# [[5 0 0 8 9 8 5 8]
#  [3 0 2 3 5 1 4 2]
#  [4 2 4 0 6 5 6 1]]
# [11 12 13  5  0  0  8  9  8  5  8  3  0  2  3  5  1  4  2  4  2  4  0  6
#   5  6  1]
# [[11 12 13 14 15 16 17 18]
#  [ 5  0  0  8  9  8  5  8]
#  [ 3  0  2  3  5  1  4  2]
#  [ 4  2  4  0  6  5  6  1]]
# [[11  5  0  0  8  9  8  5  8]
#  [12  3  0  2  3  5  1  4  2]
#  [13  4  2  4  0  6  5  6  1]]

6、位運算

bitwise_and對數(shù)組中整數(shù)的二進制形式執(zhí)行位與運算。
bitwise_or對數(shù)組中整數(shù)的二進制形式執(zhí)行位與運算。
invert對數(shù)組中整數(shù)進行位取反運算,即 0 變成 1,1 變成 0。
left_shift將數(shù)組元素的二進制形式向左移動到指定位置,右側附加相等數(shù)量的 0。
right_shift將數(shù)組元素的二進制形式向右移動到指定位置,左側附加相等數(shù)量的 0。

import numpy

if __name__ == "__main__":
    a = numpy.arange(0, 12).reshape([3, 4])
    print(a)
    b = [11, 12, 13, 14]
    print(b)
    result = numpy.bitwise_and(a, b)
    print(result)
    result = numpy.bitwise_or(a, b)
    print(a)
    result = numpy.invert(a)
    print(result)
    result = numpy.left_shift(a, 2)
    print(result)
    result = numpy.right_shift(result, 2)
    print(result)

# output:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
# [11, 12, 13, 14]
# [[ 0  0  0  2]
#  [ 0  4  4  6]
#  [ 8  8  8 10]]
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
# [[ -1  -2  -3  -4]
#  [ -5  -6  -7  -8]
#  [ -9 -10 -11 -12]]
# [[ 0  4  8 12]
#  [16 20 24 28]
#  [32 36 40 44]]
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

7、字符串處理

NumPy中對字符串的處理基于 Python 內置庫中的標準字符串函數(shù),對dtype為 numpy.string_numpy.unicode_的數(shù)組執(zhí)行向量化字符串操作,相應函數(shù)在字符數(shù)組類(numpy.char)中定義。
numpy.char.add()
依次對兩個數(shù)組的元素進行字符串連接。
numpy.char.multiply()
對數(shù)組的數(shù)值執(zhí)行多次重度連接。
numpy.char.center()
將數(shù)組的數(shù)值字符串居中,并使用指定字符在左側和右側進行填充。
numpy.char.capitalize()
將數(shù)組數(shù)值字符串的第一個字母轉換為大寫:
numpy.char.title()
將數(shù)組數(shù)值字符串的每個單詞的第一個字母轉換為大寫:
numpy.char.lower()
對數(shù)組的每個元素轉換為小寫,對每個元素調用 str.lower。
numpy.char.upper()
對數(shù)組的每個元素轉換為大寫,對每個元素調用 str.upper。
numpy.char.split()
通過指定分隔符對字符串進行分割,并返回數(shù)組。默認情況下,分隔符為空格。
numpy.char.splitlines()
以換行符作為分隔符來分割字符串,并返回數(shù)組。
numpy.char.strip()
用于移除開頭或結尾處的特定字符。
numpy.char.join()
通過指定分隔符來連接數(shù)組中的元素或字符串
numpy.char.replace()
使用新字符串替換字符串中的所有子字符串。
numpy.char.encode()
對數(shù)組中的每個元素調用 str.encode 函數(shù)。 默認編碼是 utf-8,可以使用標準 Python 庫中的編×××。
numpy.char.decode()
對編碼的元素進行 str.decode() 解碼。

8、數(shù)學函數(shù)

NumPy 包含大量的各種數(shù)學運算的函數(shù),包括三角函數(shù),算術運算的函數(shù),復數(shù)處理函數(shù)等。
numpy.sin(x, *args, **kwargs)
計算x的正弦并返回,x為弧度值
numpy.arcsin(x, *args, **kwargs)
計算x的反正弦并返回,返回為弧度值
numpy.cos(x, *args, **kwargs)
計算x的余弦并返回,x為弧度值
numpy.arccos(x, *args, **kwargs)
計算x的反余弦并返回,返回為弧度值
numpy.tan(x, *args, **kwargs)
計算x的正切并返回,x為弧度值
numpy.arctan(x, *args, **kwargs)
計算x的反正切并返回,返回為弧度值
numpy.degrees(x, *args, **kwargs)
計算x的角度值并返回,x為弧度值

import numpy

if __name__ == "__main__":
    angles = numpy.array([0, 45, 60, 90, 120, 150, 180])
    result = numpy.sin(angles * numpy.pi / 180)
    print(result)
    result = numpy.arcsin(result)
    print(numpy.degrees(result))
    result = numpy.cos(angles * numpy.pi / 180)
    print(result)
    result = numpy.arccos(result)
    print(result)
    result = numpy.tan(angles * numpy.pi / 180)
    print(result)
    result = numpy.arctan(result)
    print(result)

numpy.around(a, decimals=0, out=None)
返回指定數(shù)字的四舍五入值。
參數(shù)a表示數(shù)值,可以為數(shù)組
參數(shù)decimals表示舍入的小數(shù)位數(shù)。 默認值為0。 如果為負,整數(shù)將四舍五入到小數(shù)點左側的位置
numpy.floor(x, *args, **kwargs)
返回數(shù)值x的下舍整數(shù)
numpy.ceil(x, *args, **kwargs)
?返回數(shù)值x的上入整數(shù)。

import numpy

if __name__ == "__main__":
    a = numpy.array([1.2, 3.14, -2.5, 9.8])
    print(a)
    result = numpy.around(a,decimals=1)
    print(result)
    result = numpy.floor(a)
    print(result)
    result = numpy.ceil(a)
    print(result)

# output:
# [ 1.2   3.14 -2.5   9.8 ]
# [ 1.2  3.1 -2.5  9.8]
# [ 1.  3. -3.  9.]
# [ 2.  4. -2. 10.]

9、排序過濾

numpy.sort(a, axis=-1, kind='quicksort', order=None)
?參數(shù)a為要排序的數(shù)組
參數(shù)axis,沿著axis排序數(shù)組的軸,如果沒有數(shù)組會被展開,沿著最后的軸排序, axis=0 按列排序,axis=1 按行排序。
參數(shù)kind,用于指定排序算法,'quicksort'(快速排序),'mergesort'(歸并排序),'heapsort'(堆排序)。
order: 如果數(shù)組包含字段,則是要排序的字段。
numpy.sort()作為函數(shù)使用時,不修改被排序的原始array;array.sort()作為方法使用時,會對原始array修改為排序后數(shù)組array。
NumPy 提供了多種排序的方法,不同的排序算法的特征在于執(zhí)行速度,最壞情況性能,所需的工作空間和算法的穩(wěn)定性??焖倥判蜃顗男蔕(n^2),是不穩(wěn)定排序算法,最快的排序算法;歸并排序最壞效率為O(n*log(n)),是穩(wěn)定的排序算法;堆排序最壞效率為O(n*log(n)),是不穩(wěn)定排序算法。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, 10)
    print(a)
    # 排序不會改變原始數(shù)組
    b = numpy.sort(a)
    print(a)
    print(b)
    # 排序改變數(shù)組對象
    a.sort()
    print(a)

# output:
# [3 9 4 7 3 7 9 0 6 3]
# [3 9 4 7 3 7 9 0 6 3]
# [0 3 3 3 4 6 7 7 9 9]
# [0 3 3 3 4 6 7 7 9 9]

numpy.argsort(a, axis=-1, kind='quicksort', order=None)
返回數(shù)組值從小到大的索引值。
參數(shù)a為輸入數(shù)組
參數(shù)axis,沿著axis排序數(shù)組的軸,如果沒有數(shù)組會被展開,沿著最后的軸排序, axis=0 按列排序,axis=1 按行排序。
參數(shù)kind,用于指定排序算法,'quicksort'(快速排序),'mergesort'(歸并排序),'heapsort'(堆排序)。
order: 如果數(shù)組包含字段,則是要排序的字段。
numpy.lexsort(keys, axis=None)
對多個序列進行排序,每一列代表一個序列,排序時優(yōu)先照顧靠后的列。

import numpy

if __name__ == "__main__":
    fruits = ["banana", "apple", "copper"]
    dv = ["c", "a",  "b"]
    index = numpy.lexsort((fruits, dv))
    print(index)
    result = [fruits[i] + ", " + dv[i] for i in index]
    print(result)

# output:
# [1 2 0]
# ['apple, a', 'copper, b', 'banana, c']

numpy.msort(a)
按第一個軸對數(shù)組a進行排序,返回排序后的數(shù)組副本,相當于

numpy.sort(a, axis=0)
numpy.sort_complex(a)

對復數(shù)按照先實部后虛部的順序進行排序。
numpy.partition(a, kth, axis=-1, kind='introselect', order=None)
指定一個數(shù)kth,對數(shù)組進行分區(qū)。小于kth的排在kth前面,大于kth的排在kth后面。
numpy.argpartition(a, kth, axis=-1, kind='introselect', order=None)
可以通過關鍵字 kind 指定算法沿著指定軸對數(shù)組進行分區(qū),并返回分區(qū)后的索引。

import numpy

if __name__ == "__main__":
    x = [1, 4, 6, 5, 8, 4, 9]
    print(x)
    result = numpy.partition(x, 5)
    print(result)
    index = numpy.argpartition(x, 3)
    print(index)
    for i in index:
        print(x[i], end=" ")

# output:
# [1, 4, 6, 5, 8, 4, 9]
# [4 1 4 5 6 8 9]
# [1 0 5 3 4 2 6]
# 4 1 4 5 8 6 9

numpy.extract(condition, arr)
根據某個條件從數(shù)組中抽取元素,返回滿條件的元素
參數(shù)condition用于指示數(shù)組元素是否被提取。
參數(shù)arr表示輸入數(shù)組。

import numpy

if __name__ == "__main__":
    x = numpy.arange(9).reshape(3, 3)
    print(x)
    condition = numpy.mod(x, 2) == 0
    print(condition)
    result = numpy.extract(condition, x)
    print(result)

# output:
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]
# [[ True False  True]
#  [False  True False]
#  [ True False  True]]
# [0 2 4 6 8]

numpy.where(condition, x=None, y=None)
返回輸入數(shù)組中滿足給定條件的元素的索引

import numpy

if __name__ == "__main__":
    x = numpy.random.randint(0, 10, 10)
    print(x)
    condition = numpy.where(x > 5)
    print(condition)
    result = x[condition]
    print(result)

# output:
# [1 7 5 5 9 9 7 0 2 8]
# (array([1, 4, 5, 6, 9]),)
# [7 9 9 7 8]

numpy.nonzero(a)
返回輸入數(shù)組中非零元素的索引。

import numpy

if __name__ == "__main__":
    x = numpy.random.randint(0, 10, 10)
    print(x)
    y = numpy.nonzero(x)
    print(y)
    result = x[y]
    print(result)

# output:
# [4 9 0 5 0 3 5 9 8 2]
# (array([0, 1, 3, 5, 6, 7, 8, 9]),)
# [4 9 5 3 5 9 8 2]

numpy.argmax(a, axis=None, out=None)
沿給定軸返回數(shù)組中最大元素的索引
numpy.argmin(a, axis=None, out=None)
沿給定軸返回數(shù)組中最小元素的索引

import numpy

if __name__ == "__main__":
    x = numpy.random.randint(0, 10, 10)
    print(x)
    y = numpy.argmax(x)
    print(y)
    result = x[y]
    print(result)
    print(numpy.max(x))

    y = numpy.argmin(x)
    print(y)
    result = x[y]
    print(result)
    print(numpy.min(x))

# output:
# [3 4 7 3 6 9 4 3 4 4]
# 5
# 9
# 9
# 0
# 3
# 3

10、字節(jié)交換

計算機中,多字節(jié)對象通常被存儲為連續(xù)的字節(jié)序列。字節(jié)順序是跨越多字節(jié)的程序對象的存儲規(guī)則。
大端模式:數(shù)據的高字節(jié)保存在內存的低地址中,而數(shù)據的低字節(jié)保存在內存的高地址中,大端模式的地址由小向大增加,而數(shù)據從高位往低位放。
小端模式:數(shù)據的高字節(jié)保存在內存的高地址中,而數(shù)據的低字節(jié)保存在內存的低地址中,小端模式將地址的高低和數(shù)據位權有效地結合起來,高地址部分權值高,低地址部分權值低。
numpy.ndarray.byteswap(self, inplace=False)
將 ndarray 中每個元素中的字節(jié)進行大小端轉換。

import numpy

if __name__ == "__main__":
    x = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=numpy.int16)
    print(x)
    for i in x:
        print(hex(i), end=" ")
    print("\n")
    result = x.byteswap(True)
    for i in result:
        print(hex(i), end=" ")

# output:
# [1 2 3 4 5 6 7 8 9]
# 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 
# 
# 0x100 0x200 0x300 0x400 0x500 0x600 0x700 0x800 0x900 

11、副本和視圖

副本是一個數(shù)據的完整的拷貝,如果對副本進行修改,不會影響到原始數(shù)據,物理內存不在同一位置。
視圖是數(shù)據的引用,通過視圖可訪問、操作原有數(shù)據,但原有數(shù)據不會產生拷貝。如果對視圖進行修改,會影響到原始數(shù)據,物理內存在同一位置。
在 Python 中,對象賦值本質是對象的引用。當創(chuàng)建一個對象,然后將其賦給另一個變量時,Python并沒有拷貝對象,而只是拷貝對象的引用,稱為淺拷貝。
在 Python中,當進行賦值操作時,為使兩個變量互不影響,可以使用 copy 模塊中的 deepcopy 方法,稱為深拷貝。
通常,切片操作會返回原數(shù)據的視圖,調用 ndarray 的 view() 函數(shù)會產生視圖;切片操作中調用deepCopy()函數(shù)會產生副本,調用 ndarray 的 copy() 函數(shù)會產生副本。
簡單的賦值不會創(chuàng)建數(shù)組對象的副本。

import numpy

if __name__ == "__main__":
    x = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=numpy.int16)
    y = x
    print(id(x))
    print(id(y))

    y.shape = [3, 3]
    print(x)
    print(y)

# output:
# 140621988193024
# 140621988193024
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

ndarray.view() 方會創(chuàng)建一個新的數(shù)組對象,view方法創(chuàng)建的新數(shù)組的維數(shù)更改不會更改原始數(shù)據的維數(shù)。

import numpy

if __name__ == "__main__":
    x = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=numpy.int16)
    y = x.view()
    print(id(x))
    print(id(y))
    y.shape = [3, 3]
    print(x)
    print(y)

# output:
# 140025825882960
# 140025825245024
# [1 2 3 4 5 6 7 8 9]
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

使用切片創(chuàng)建視圖修改數(shù)據會影響到原始數(shù)組,視圖雖然指向原數(shù)據,但會創(chuàng)建新的對象。

import numpy

if __name__ == "__main__":
    x = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=numpy.int16)
    a = x[2:]
    b = x[5:]
    print(id(x))
    print(id(a))
    print(id(b))
    print(a)
    print(b)
    a[0] = 11
    b[0] = 12
    print(a)
    print(b)
    print(x)

# output:
# 139764960379728
# 139764959741792
# 139764836999776
# [3 4 5 6 7 8 9]
# [6 7 8 9]
# [11  4  5 12  7  8  9]
# [12  7  8  9]
# [ 1  2 11  4  5 12  7  8  9]

ndarray.copy() 函數(shù)創(chuàng)建一個副本, 對副本數(shù)據進行修改,不會影響到原始數(shù)據。

import numpy

if __name__ == "__main__":
    x = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=numpy.int16)
    y = x.copy()
    print(id(x))
    print(id(y))
    y[0] = 10
    print(x)
    print(y)

# output:
# 139690155443024
# 139690154805088
# [1 2 3 4 5 6 7 8 9]
# [10  2  3  4  5  6  7  8  9]

numpy.copy(a, order='K')
創(chuàng)建給定數(shù)組a的一個副本,可以作為數(shù)組的方法使用。

import numpy

if __name__ == "__main__":
    array_normal = numpy.random.normal(loc=1.75, scale=0.1, size=[5, 5])
    print(array_normal)
    b = array_normal[1, 2].copy()
    print(b)
    # 截取第1行至第3行(不包括第3行),第2列至第4列(不包括第4列)的數(shù)據
    c = numpy.copy(array_normal[1:3, 2:4])
    print(c)

# output:
# [[1.71679806 1.85533715 1.74308905 1.75119872 1.79173827]
#  [1.65084866 1.8366689  1.72241261 1.71965308 1.58003833]
#  [1.86165973 1.84692966 1.73746162 1.81721825 1.75710235]
#  [1.95509949 1.90046488 1.71245928 2.00848233 1.73175004]
#  [1.64957638 1.80259583 1.84005861 1.85791674 1.825334  ]]
# 1.7224126132538562
# [[1.72241261 1.71965308]
#  [1.73746162 1.81721825]]

五、NumPy.matlib矩陣模塊

1、matlib模塊簡介

NumPy 中包含了一個矩陣庫 numpy.matlib,numpy.matlib模塊中的函數(shù)返回的是一個矩陣,而不是 ndarray 對象。
一個?mxn的矩陣是一個由m行(row)和n列(column)元素排列成的矩形陣列,矩陣里的元素可以是數(shù)字、符號或數(shù)學式。

2、矩陣創(chuàng)建

numpy.matlib.empty(shape, dtype, order)
創(chuàng)建矩陣,填充隨機數(shù)據。
shape參數(shù),定義新矩陣形狀的整數(shù)或整數(shù)元組。
dtype參數(shù),可選,數(shù)據類型。
order參數(shù),可選項為C(行序優(yōu)先) 或者 F(列序優(yōu)先)。
矩陣是二維的,而 ndarray 是一個 n 維數(shù)組。 矩陣與ndarray是可互換的。
numpy.matlib.zeros(shape, dtype=None, order='C'):
創(chuàng)建一個以 0 填充的矩陣。
numpy.matlib.ones(shape, dtype=None, order='C'):
創(chuàng)建一個以 1 填充的矩陣。
numpy.matlib.eye(n, M,k, dtype)
numpy.matlib.eye() 函數(shù)返回一個矩陣,對角線元素為 1,其他位置為零。
n: 返回矩陣的行數(shù)
M: 返回矩陣的列數(shù),默認為 n
k: 對角線的索引
dtype: 數(shù)據類型
numpy.matlib.identity(n,dtype=None)
返回給定大小的單位矩陣。
單位矩陣是個方陣,從左上角到右下角的對角線(稱為主對角線)上的元素均為 1,除此以外全都為 0。
Python3快速入門(十二)——NumPy
numpy.matlib.rand(*args):
創(chuàng)建一個給定大小的矩陣,數(shù)據是隨機填充的。

六、NumPy.linalg線性代數(shù)模塊

1、linalg線性代數(shù)模塊

NumPy 提供了線性代數(shù)函數(shù)庫?linalg,linalg庫包含了線性代數(shù)所需的所有功能。

2、線性代數(shù)運算

numpy.dot(a, b, out=None)
兩個數(shù)組的點積,對應數(shù)組元素相乘。
a?: ndarray 數(shù)組
b?: ndarray 數(shù)組
out?: ndarray, 可選,用來保存dot()的計算結果
?對于兩個一維的數(shù)組,計算兩個數(shù)組對應下標元素的乘積和(數(shù)學上稱為內積);對于二維數(shù)組,計算兩個數(shù)組的矩陣乘積;對于多維數(shù)組,通用計算公式如下,即結果數(shù)組中的每個元素都是:數(shù)組a的最后一維上的所有元素與數(shù)組b的倒數(shù)第二位上的所有元素的乘積和。
numpy.vdot(a, b)
兩個向量的點積。
如果第一個參數(shù)是復數(shù),那么其共軛復數(shù)會用于計算。 如果參數(shù)是多維數(shù)組,會被展開。
numpy.inner(a, b)
返回一維數(shù)組的向量內積。對于更高的維度,返回最后一個軸上的和的乘積。
numpy.matmul(x1, x2, *args, **kwargs)
返回兩個數(shù)組的矩陣乘積,但如果任一參數(shù)的維數(shù)大于2,則將其視為存在于最后兩個索引的矩陣的棧,并進行相應廣播。
另一方面,如果任一參數(shù)是一維數(shù)組,則通過在其維度上附加 1 來將其提升為矩陣,并在乘法后被去除。
對于二維數(shù)組,它就是矩陣乘法:
numpy.linalg.det(a)
計算輸入矩陣的行列式。
行列式在線性代數(shù)中是非常有用的值,從方陣的對角元素計算。 對于 2×2 矩陣,是左上和右下元素的乘積與其他兩個的乘積的差。
對于矩陣[[a,b],[c,d]],行列式計算為 ad-bc。 較大的方陣被認為是 2×2 矩陣的組合。
numpy.linalg.solve(a, b)
求解線性矩陣方程。
numpy.linalg.inv(a)
計算矩陣的乘法逆矩陣。
逆矩陣(inverse matrix):設A是數(shù)域上的一個n階矩陣,若在相同數(shù)域上存在另一個n階矩陣B,使得: AB=BA=E ,則稱B是A的逆矩陣,而A則被稱為可逆矩陣,E為單位矩陣。

七、NumPy IO操作

Numpy 可以讀寫磁盤上的文本數(shù)據或二進制數(shù)據。
NumPy 為 ndarray 對象引入了一個簡單的文件格式:npy。
npy 文件用于存儲重建 ndarray 所需的數(shù)據、圖形、dtype 和其他信息。
numpy.save(file, arr, allow_pickle=True, fix_imports=True)
將數(shù)組以未壓縮的原始二進制格式保存在擴展名為 .npy 的文件中。
參數(shù)file,要保存的文件,擴展名為 .npy,如果文件路徑末尾沒有擴展名 .npy,擴展名會被自動加上。
參數(shù)arr,要保存的數(shù)組。
參數(shù)allow_pickle, 可選,布爾值,允許使用 Python pickles 保存對象數(shù)組,Python 中的 pickle 用于在保存到磁盤文件或從磁盤文件讀取前,對對象進行序列化和反序列化。
參數(shù)fix_imports:,可選,為了方便 Pyhton2 中讀取 Python3 保存的數(shù)據。
load(file, mmap_mode=None, allow_pickle=False, fix_imports=True,encoding='ASCII')
加載npy文件
file參數(shù),文件名。

import numpy

if __name__ == "__main__":
    a = numpy.arange(0, 12).reshape([3, 4])
    numpy.save("outfile.npy", a)

    b = numpy.load("outfile.npy")
    print(b)

# output:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

numpy.savez(file, *args, **kwds)
將多個數(shù)組以未壓縮的原始二進制格式保存在擴展名為 .npz 的文件中。
參數(shù)file,要保存的文件,擴展名為?.npz,如果文件路徑末尾沒有擴展名?.npz,擴展名會被自動加上。
參數(shù)args,要保存的數(shù)組,可以使用關鍵字參數(shù)為數(shù)組起一個名字,非關鍵字參數(shù)傳遞的數(shù)組會自動起名為?arr_0,?arr_1。
參數(shù)kwds:,要保存的數(shù)組使用關鍵字名稱。

import numpy

if __name__ == "__main__":
    a = numpy.array([[1, 2, 3], [4, 5, 6]])
    b = numpy.arange(0, 1.0, 0.1)
    c = numpy.sin(b)
    # c 使用了關鍵字參數(shù) sin_array
    numpy.savez("outfile.npz", a, b, sin_array=c)
    r = numpy.load("outfile.npz")
    print(r.files)  # 查看各個數(shù)組名稱
    print(r["arr_0"])
    print(r["arr_1"])
    print(r["sin_array"])

# output:
# ['sin_array', 'arr_0', 'arr_1']
# [[1 2 3]
#  [4 5 6]]
# [0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
# [0.         0.09983342 0.19866933 0.29552021 0.38941834 0.47942554
#  0.56464247 0.64421769 0.71735609 0.78332691]

numpy.loadtxt(file, dtype=int, delimiter=' ')
以簡單的文本文件格式讀取數(shù)據。
參數(shù)file為要加載的文件名
參數(shù)dtype為數(shù)據類型
參數(shù) delimiter 可以指定各種分隔符、針對特定列的轉換器函數(shù)、需要跳過的行數(shù)等。
numpy.savetxt(file, a, fmt="%d", delimiter=",")
以簡單的文本文件格式存儲數(shù)據。
參數(shù)file為要加載的文件名
參數(shù)a為要保存的數(shù)組
參數(shù)fmt為格式化字符串
參數(shù) delimiter 可以指定各種分隔符、針對特定列的轉換器函數(shù)、需要跳過的行數(shù)等。

import numpy

if __name__ == "__main__":
    b = numpy.arange(0, 1.0, 0.1)
    c = numpy.sin(b)
    numpy.savetxt("outfile.txt", (b, c))
    r = numpy.loadtxt("outfile.txt")
    print(r)

# output:
# [[0.         0.1        0.2        0.3        0.4        0.5
#   0.6        0.7        0.8        0.9       ]
#  [0.         0.09983342 0.19866933 0.29552021 0.38941834 0.47942554
#   0.56464247 0.64421769 0.71735609 0.78332691]]

網站題目:Python3快速入門(十二)——NumPy
轉載來源:http://bm7419.com/article8/ijpgip.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供微信公眾號、網站制作、網站設計、全網營銷推廣建站公司、網站策劃

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

網站優(yōu)化排名