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

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

1、NumPy簡介

一、NumPy簡介

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

二、NumPy的優缺點

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

三、NumPy安裝

pip install --user numpy
--user 選項能夠設置只安裝在當前的用戶下,而不是寫入到系統目錄。api

四、NumPy數據類型

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

五、dtype數據類型對象

數據類型對象dtype用於描述與數組對應的內存區域如何使用,依賴以下幾個方面:
(1)數據的類型(整數,浮點數或者 Python 對象)
(2)數據的大小(例如, 整數使用多少個字節存儲)
(3)數據的字節順序(小端法或大端法)
(4)在結構化類型的狀況下,字段的名稱、每一個字段的數據類型和每一個字段所取的內存塊的部分。
(5)若是數據類型是子數組,其形狀和數據類型。
(6)字節順序是經過對數據類型預先設定"<"或">"來決定的。"<"意味着小端法(最小值存儲在最小的地址,即低位組放在最前面)。">"意味着大端法(最重要的字節存儲在最小的地址,即高位組放在最前面)。
dtype 對象使用如下語法構造的:
numpy.dtype(object, align, copy)
object - 要轉換爲的數據類型對象
align - 若是爲 true,填充字段使其相似 C 的結構體。
copy - 複製 dtype 對象 ,若是爲 false,則是對內置數據類型對象的引用
一個結構化數據類型 student,包含字符串字段 name,整數字段 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.)]

2、ndarray

一、ndarray簡介

ndarray是NumPy的核心,ndarray封裝了python原生的同數據類型的n維數組,經過正整數元組索引。
ndarray內部結構以下:
(1)一個指向數據(內存或內存映射文件中的一塊數據)的指針。
(2)數據類型(dtype),描述在數組中的固定大小值的格子。
(3)一個表示數組形狀(shape)的元組,表示各維度大小的元組。
(4)一個跨度元組(stride),其中整數指的是爲了前進到當前維度下一個元素須要"跨過"的字節數。
Python3快速入門(十二)——NumPy
ndarray 和 標準Python 數組的區別以下:
(1)ndarray 在建立時具備固定的大小, 更改ndarray的大小將建立一個新數組並刪除原來的數組,與Python的原生數組對象(能夠動態增加)不一樣。
(2)ndarray 中的元素必須具備相同的數據類型,所以在內存中的大小相同。
(3)ndarray 有助於對大量數據進行高級數學和其它類型的操做。 一般,ndarray 的執行效率更高,比使用Python原生數組的代碼更少。
(4)大部分基於Python的科學和數學軟件包都使用NumPy數組,儘管一般也支持Python原生數組做爲參數,但在處理前仍然會將輸入數組轉換爲NumPy數組,並且一般輸出爲NumPy數組。爲了高效地使用當今基於Python的科學計算工具,須要知道如何使用NumPy數組。app

二、ndarray 對象的屬性

ndarray 對象提供的關鍵屬性以下:
ndarray.ndim:數組的軸(維度)的個數,維度的數量被稱爲rank。
ndarray.shape:數組的維度,是一個整數的元組,表示每一個維度中數組的大小。對於n行和m列的矩陣,shape是(n,m)。所以,shape元組的長度就是rank或維度的個數 ndim。
ndarray.size:數組元素的總數,等於shape的元素的乘積。
ndarray.dtype:描述數組中元素類型的對象。可使用標準的Python類型建立或指定dtype。NumPy提供本身的類型,如numpy.int3二、numpy.int16和numpy.float64。
ndarray.itemsize:數組中每一個元素的字節大小,等於 ndarray.dtype.itemsize。元素爲 float64 類型的數組的 itemsize 爲8(=64/8),而 complex32 類型的數組的 itemsize 爲4(=32/8)。
ndarray.flags:ndarray對象的內存信息。
ndarray.real:ndarray元素的實部
ndarray.imag:ndarray 元素的虛部
ndarray.data:緩衝區包含數組的實際元素。
Ndarray.flags的內存信息屬性以下:
C_CONTIGUOUS (C):數據是在一個單一的C風格的連續段中
F_CONTIGUOUS (F):數據是在一個單一的Fortran風格的連續段中
OWNDATA (O):數組擁有本身所使用的內存或從另外一個對象中借用
WRITEABLE (W:)數據區域能夠被寫入,將值設置爲 False,則數據爲只讀。
ALIGNED (A):數據和全部元素都適當地對齊到硬件上。
UPDATEIFCOPY (U):數組是其它數組的一個副本,當數組被釋放時,原數組的內容將被更新。框架

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'>

三、建立數組

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

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)
建立數組,p_object爲數組或序列,dtype爲數組元素類型機器學習

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)
建立數組,a爲數組或序列,dtype爲數組元素類型ide

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 用於實現動態數組。
buffer 參數爲人以對象,以流的形式讀入轉化成 ndarray 對象。buffer 是字符串的時候,Python3 默認 str 是 Unicode 類型,因此要轉成 bytestring 在原 str 前加上 b。
dtype參數,數組的數據類型,可選。
count參數,讀取的數據量,默認爲-1,讀取全部的數據。
offset參數,讀取的起始位置,默認爲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 對象,返回一維數組。
Iterable參數,可迭代對象。
dtype參數,數組的數據類型,可選。
count參數,讀取的數據數量,默認爲-1,讀取全部數據。

import numpy

if __name__ == "__main__":
    # 使用 range 函數建立列表對象
    l = range(10)
    it = iter(l)
    # 使用迭代器建立 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')
建立數值爲1的數組,shape是數組的形狀,dtype是數值類型。

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')
建立數值爲0的數組,shape是數組的形狀,dtype是數值類型。

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')
建立指定數值的數組,shape是數組的形狀,fill_value是數值,dtype是數值類型。

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')
建立單位矩陣,N爲行數,M爲列數

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)
建立對角矩陣,v是主對角線數值,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)
建立指定shape的數組,數值範圍在0~1之間。dn是可變參數,接收多個參數用於指定數組的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)
建立指定範圍內的數值的數或數組,low爲下限,high爲上限,size爲個數,能夠爲序列,用於指定數組的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')
建立指定範圍內的數值的數或數組,low爲下限,high爲上限,size爲個數,能夠爲序列,用於指定數組的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)
建立一維數組,其中包含位於半開區間[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)
建立N個在閉區間[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)
建立給定均值loc、標準差scale、維度size的正態分佈

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

四、ndarray索引

ndarray對象的內容能夠經過索引或切片來訪問和修改,與 Python 中 list 的切片操做同樣。
ndarray 數組能夠基於 0 - n 的下標進行索引,切片對象能夠經過內置的 slice 函數,並設置 start, stop 及 step 參數進行,從原數組中切割出一個新數組。
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數組能夠經過整數數組進行索引,一般須要分別構造行索引和列索引的數組,經過行索引數組和列索引數組組合使用最終定位數組的索引。

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能夠經過一個布爾數組來進行索,布爾索引經過布爾運算(如:比較運算符)來獲取符合指定條件的元素的數組。

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]

五、數組修改

numpy.ndarray.reshape(a, newshape, order='C')
把指定的數組改變形狀,但元素個數不變;有返回值,即不對原始多維數組進行修改。a是數組,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)
把指定的數組改變形狀,但元素個數可變,不足補0。numpy.resize做爲含磺素使用時,不會對原始數組進行修改,返回新的結果數組;array.resize做爲方法使用時,無返回值,會對原始多維數組進行修改。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, 10)
    print(a)
    # 不修改原始數組
    b = numpy.resize(a, [3, 4])
    print(a)
    print(b)
    # 修改原始數組
    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]]

3、NumPy 數組迭代

一、迭代數組簡介

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

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,

二、遍歷順序控制

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

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

order='F',表示Fortran order,即列序優先;order='C',表示C order,即行序優先。

三、遍歷修改數組元素值

nditer 對象有一個可選參數 op_flags。 默認狀況下,nditer將視待迭代遍歷的數組爲只讀對象(read-only),爲了在遍歷數組的同時,實現對數組元素值得修改,必須指定 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]]

四、外部循環

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

五、廣播迭代

若是兩個數組是可廣播的,nditer 組合對象可以同時迭代。 假設數組 a 的維度爲 3X4,數組 b 的維度爲 1X4 ,則使用迭代器(數組 b 被廣播到 a 的大小)以下:

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,

4、NumPy運算

一、條件運算

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

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]

二、統計函數

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

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 100, [3, 5])
    print(a)
    # 統計整個矩陣的最大值
    result = numpy.amax(a)
    print(result)
    # 統計矩陣中每一列的最大值
    result = numpy.amax(a, axis=0)
    print(result)
    # 統計矩陣中每一行的最大值
    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)
根據指定軸統計矩陣的最小值,axis=0統計矩陣中每一列的最小值,axis=1統計矩陣中每一行的最小值,默認統計矩陣中的最小值。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 100, [3, 5])
    print(a)
    # 統計整個矩陣的最小值
    result = numpy.amin(a)
    print(result)
    # 統計矩陣中每一列的最小值
    result = numpy.amin(a, axis=0)
    print(result)
    # 統計矩陣中每一行的最小值
    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)
根據指定軸統計矩陣的平均值,axis=0統計矩陣中每一列的平均值,axis=1統計矩陣中每一行的平均值,默認統計矩陣中的平均值。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 100, [3, 5])
    print(a)
    # 統計整個矩陣的平均值
    result = numpy.mean(a)
    print(result)
    # 統計矩陣中每一列的平均值
    result = numpy.mean(a, axis=0)
    print(result)
    # 統計矩陣中每一行的平均值
    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)
根據指定軸統計矩陣的方差,axis=0統計矩陣中每一列的方差,axis=1統計矩陣中每一行的方差,默認統計矩陣中的方差。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 100, [3, 5])
    print(a)
    # 統計整個矩陣的方差
    result = numpy.std(a)
    print(result)
    # 統計矩陣中每一列的方差
    result = numpy.std(a, axis=0)
    print(result)
    # 統計矩陣中每一行的方差
    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)
根據指定軸統計矩陣的求和,axis=0統計矩陣中每一列的求和,axis=1統計矩陣中每一行的求和,默認統計矩陣中的求和。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 100, [3, 5])
    print(a)
    # 統計整個矩陣的求和
    result = numpy.sum(a)
    print(result)
    # 統計矩陣中每一列的求和
    result = numpy.sum(a, axis=0)
    print(result)
    # 統計矩陣中每一行的求和
    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)
計算數組中元素最大值與最小值的差(最大值 - 最小值)

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

百分位數是統計中使用的度量,表示小於這個值的觀察值的百分比
參數a,輸入數組
參數q,要計算的百分位數,在 0 ~ 100 之間
參數axis: 沿着計算百分位數的軸
numpy.median(a, axis=None, out=None, overwrite_input=False, keepdims=False)
用於計算數組 a 中元素的中位數(中值)
numpy.average(a, axis=None, weights=None, returned=False)
根據各自的權重計算數組中元素的加權平均值。
參數a,輸入數組
參數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)

三、算術運算

數組與數的運算包括加、減、乘、除、取整、取模,可使用函數也可使用操做符。
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)
計算輸入數組中相應元素的相除後的餘數
numpy.power(x1, x2, *args, **kwargs)
將x1做爲底數,計算x1的x2次冪。
numpy.reciprocal(x, *args, **kwargs)
返回x的倒數。

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

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

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]

四、廣播

廣播(Broadcast)是 numpy 對不一樣shape的數組進行數值計算的方式, 對數組的算術運算一般在相應的元素上進行。
若是兩個數組進行運算時必需要求shape相同,當運算中的 2 個數組的shape不一樣時,numpy 將自動觸發廣播機制。
廣播機制的規則以下:
(1)讓全部輸入數組都向其中形狀最長的數組看齊,形狀中不足的部分都經過在前面加 1 補齊。
(2)輸出數組的形狀是輸入數組形狀的各個維度上的最大值。
(3)若是輸入數組的某個維度和輸出數組的對應維度的長度相同或者其長度爲 1 時,這個數組可以用來計算,不然出錯。
(4)當輸入數組的某個維度的長度爲 1 時,沿着此維度運算時都用此維度上的第一組值。
若是條件不知足,拋出 "ValueError: frames are not aligned" 異常。
4x3 的二維數組與1x 3 的一維數組相加,等效於把一維數組 在二維上重複 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]]

五、矩陣運算

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

import numpy

if __name__ == "__main__":
    # 成績,期末考試成績和日常做業成績組成
    score = numpy.array([[100, 87], [88, 87], [78, 80], [65, 89]])
    # 權重因子,期末成績佔70%,平時做業成績佔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)
矩陣垂直拼接(兩個矩陣列數必須相同,行數隨意),參數tup爲數組的元組。

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)
矩陣水平拼接(兩個矩陣行數必須相同,列數隨意),參數tup爲數組的元組。

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)
矩陣刪除,參數arr爲數組;參數obj爲要刪除的對象;參數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)
矩陣添加,參數arr爲數組;參數values爲要追加的對象;參數axis爲軸,axis=0表示追加到行,axis=1表示追加到列,默認添加到全部數組元素的尾部。

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)
矩陣插入,參數arr爲數組,obj爲插入位置索引,values爲插入的值,參數axis爲軸,axis=0表示插入到行,axis=1表示插入到列,默認插入到全部數組元素的序列的指定位置。

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

六、位運算

bitwise_and對數組中整數的二進制形式執行位與運算。
bitwise_or對數組中整數的二進制形式執行位與運算。
invert對數組中整數進行位取反運算,即 0 變成 1,1 變成 0。
left_shift將數組元素的二進制形式向左移動到指定位置,右側附加相等數量的 0。
right_shift將數組元素的二進制形式向右移動到指定位置,左側附加相等數量的 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]]

七、字符串處理

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

八、數學函數

NumPy 包含大量的各類數學運算的函數,包括三角函數,算術運算的函數,複數處理函數等。
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)
返回指定數字的四捨五入值。
參數a表示數值,能夠爲數組
參數decimals表示舍入的小數位數。 默認值爲0。 若是爲負,整數將四捨五入到小數點左側的位置
numpy.floor(x, *args, **kwargs)
返回數值x的下舍整數
numpy.ceil(x, *args, **kwargs)
 返回數值x的上入整數。

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

九、排序過濾

numpy.sort(a, axis=-1, kind='quicksort', order=None)
 參數a爲要排序的數組
參數axis,沿着axis排序數組的軸,若是沒有數組會被展開,沿着最後的軸排序, axis=0 按列排序,axis=1 按行排序。
參數kind,用於指定排序算法,'quicksort'(快速排序),'mergesort'(歸併排序),'heapsort'(堆排序)。
order: 若是數組包含字段,則是要排序的字段。
numpy.sort()做爲函數使用時,不修改被排序的原始array;array.sort()做爲方法使用時,會對原始array修改成排序後數組array。
NumPy 提供了多種排序的方法,不一樣的排序算法的特徵在於執行速度,最壞狀況性能,所需的工做空間和算法的穩定性。快速排序最壞效率O(n^2),是不穩定排序算法,最快的排序算法;歸併排序最壞效率爲O(n*log(n)),是穩定的排序算法;堆排序最壞效率爲O(n*log(n)),是不穩定排序算法。

import numpy

if __name__ == "__main__":
    a = numpy.random.randint(0, 10, 10)
    print(a)
    # 排序不會改變原始數組
    b = numpy.sort(a)
    print(a)
    print(b)
    # 排序改變數組對象
    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)
返回數組值從小到大的索引值。
參數a爲輸入數組
參數axis,沿着axis排序數組的軸,若是沒有數組會被展開,沿着最後的軸排序, axis=0 按列排序,axis=1 按行排序。
參數kind,用於指定排序算法,'quicksort'(快速排序),'mergesort'(歸併排序),'heapsort'(堆排序)。
order: 若是數組包含字段,則是要排序的字段。
numpy.lexsort(keys, axis=None)
對多個序列進行排序,每一列表明一個序列,排序時優先照顧靠後的列。

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)
按第一個軸對數組a進行排序,返回排序後的數組副本,至關於

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

對複數按照先實部後虛部的順序進行排序。
numpy.partition(a, kth, axis=-1, kind='introselect', order=None)
指定一個數kth,對數組進行分區。小於kth的排在kth前面,大於kth的排在kth後面。
numpy.argpartition(a, kth, axis=-1, kind='introselect', order=None)
能夠經過關鍵字 kind 指定算法沿着指定軸對數組進行分區,並返回分區後的索引。

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)
根據某個條件從數組中抽取元素,返回滿條件的元素
參數condition用於指示數組元素是否被提取。
參數arr表示輸入數組。

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)
返回輸入數組中知足給定條件的元素的索引

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)
返回輸入數組中非零元素的索引。

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)
沿給定軸返回數組中最大元素的索引
numpy.argmin(a, axis=None, out=None)
沿給定軸返回數組中最小元素的索引

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

十、字節交換

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

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

十一、副本和視圖

副本是一個數據的完整的拷貝,若是對副本進行修改,不會影響到原始數據,物理內存不在同一位置。
視圖是數據的引用,經過視圖可訪問、操做原有數據,但原有數據不會產生拷貝。若是對視圖進行修改,會影響到原始數據,物理內存在同一位置。
在 Python 中,對象賦值本質是對象的引用。當建立一個對象,而後將其賦給另外一個變量時,Python並無拷貝對象,而只是拷貝對象的引用,稱爲淺拷貝。
在 Python中,當進行賦值操做時,爲使兩個變量互不影響,可使用 copy 模塊中的 deepcopy 方法,稱爲深拷貝。
一般,切片操做會返回原數據的視圖,調用 ndarray 的 view() 函數會產生視圖;切片操做中調用deepCopy()函數會產生副本,調用 ndarray 的 copy() 函數會產生副本。
簡單的賦值不會建立數組對象的副本。

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() 方會建立一個新的數組對象,view方法建立的新數組的維數更改不會更改原始數據的維數。

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

使用切片建立視圖修改數據會影響到原始數組,視圖雖然指向原數據,但會建立新的對象。

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() 函數建立一個副本, 對副本數據進行修改,不會影響到原始數據。

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')
建立給定數組a的一個副本,能夠做爲數組的方法使用。

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列)的數據
    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]]

5、NumPy.matlib矩陣模塊

一、matlib模塊簡介

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

二、矩陣建立

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

6、NumPy.linalg線性代數模塊

一、linalg線性代數模塊

NumPy 提供了線性代數函數庫 linalg,linalg庫包含了線性代數所需的全部功能。

二、線性代數運算

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

7、NumPy IO操做

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

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)
將多個數組以未壓縮的原始二進制格式保存在擴展名爲 .npz 的文件中。
參數file,要保存的文件,擴展名爲 .npz,若是文件路徑末尾沒有擴展名 .npz,擴展名會被自動加上。
參數args,要保存的數組,可使用關鍵字參數爲數組起一個名字,非關鍵字參數傳遞的數組會自動起名爲 arr_0, arr_1。
參數kwds:,要保存的數組使用關鍵字名稱。

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 使用了關鍵字參數 sin_array
    numpy.savez("outfile.npz", a, b, sin_array=c)
    r = numpy.load("outfile.npz")
    print(r.files)  # 查看各個數組名稱
    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=' ')
以簡單的文本文件格式讀取數據。
參數file爲要加載的文件名
參數dtype爲數據類型
參數 delimiter 能夠指定各類分隔符、針對特定列的轉換器函數、須要跳過的行數等。
numpy.savetxt(file, a, fmt="%d", delimiter=",")
以簡單的文本文件格式存儲數據。
參數file爲要加載的文件名
參數a爲要保存的數組
參數fmt爲格式化字符串
參數 delimiter 能夠指定各類分隔符、針對特定列的轉換器函數、須要跳過的行數等。

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]]
相關文章
相關標籤/搜索