天天看點

python輸入數字成數組_如果不懂 numpy,請别說自己是 python 程式員

原标題:如果不懂 numpy,請别說自己是 python 程式員

作者:牧馬人 (本文來自作者投稿)

0. 前言

python輸入數字成數組_如果不懂 numpy,請别說自己是 python 程式員

大約七八年前,我曾經用 pyOpenGL 畫過地球磁層頂的三維模型,這段代碼至今仍然還運作在某科研機構裡。在那之前,我一直覺得自己是一個合(you)格(xiu)的 python 程式員,似乎無所不能。但磁層頂模型的顯示效果令我沮喪——盡管這個模型隻有十幾萬個頂點,拖拽、縮放卻非常卡頓。最終,我把頂點數量删減到兩萬左右,以兼顧模型品質和響應速度,才勉強傳遞了這個任務。從此我開始懷疑 python 的性能,甚至一度懷疑 python 是否還是我的首選工具。

幸運的是,後來我遇到了 numpy 這個神器。numpy 是 python 科學計算的基礎軟體包,提供多了維數組對象,多種派生對象(掩碼數組、矩陣等)以及用于快速操作數組的函數及 API,它包括數學、邏輯、數組形狀變換、排序、選擇、I/O 、離散傅立葉變換、基本線性代數、基本統計運算、随機模拟等等。

了解 numpy之後,我才想明白當初磁層頂的三維模型之是以慢,是因為使用了 list(python 數組)而不是 ndarray(numpy 數組)存儲資料。有了 numpy,python 程式員才有可能寫出媲美 C 語言運作速度的代碼。熟悉 numpy,才能學會使用 pyOpenGL / pyOpenCV / pandas / matplotlib 等資料處理及可視化的子產品。

事實上,numpy 的資料組織結構,尤其是數組(numpy.ndarray),幾乎已經成為所有資料處理與可視化子產品的标準資料結構了(這一點,類似于在機器學習領域 python 幾乎已經成為首選工具語言)。越來越多的基于 python 的科學和數學軟體包使用 numpy 數組,雖然這些工具通常都支援 python 的原生數組作為參數,但它們在處理之前會還是會将輸入的數組轉換為 numpy 的數組,而且也通常輸出為 numpy 數組。在 python 的圈子裡,numpy 的重要性和普遍性日趨增強。換句話說,為了高效地使用當今科學/數學基于 python 的工具(大部分的科學計算工具),你隻知道如何使用 python 的原生數組類型是不夠的,還需要知道如何使用 numpy 數組。

總結:在這個 AI 和 ML 霸屏的時代,如果不懂 numpy,請别說自己是 python 程式員。

1. list VS ndarray

numpy 的核心是 ndarray 對象(numpy 數組),它封裝了 python 原生的同資料類型的 n 維數組(python 數組)。numpy 數組和 python 數組之間有幾個重要的差別:

numpy 數組一旦建立,其元素數量就不能再改變了。 增删 ndarray 元素的操作,意味着建立一個新數組并删除原來的數組。python 數組的元素則可以動态增減不同,

numpy 數組中的元素都需要具有相同的資料類型,是以在記憶體中的大小相同。 python 數組則無此要求。

numpy 數組的方法涵蓋了大量數學運算和複雜操作,許多方法在最外層的 numpy 命名空間中都有對應的映射函數。和 python 數組相比,numpy 數組的方法功能更強大,執行效率更高,代碼更簡潔。

然而,以上的差異并沒有真正展現出 ndarray 的優勢之所在,ndarray 的精髓在于 numpy 的兩大特征:矢量化(vectorization)和廣播(broadcast)。矢量化可以了解為代碼中沒有顯式的循環、索引等,廣播可以了解為隐式地對每個元素實施操作。矢量化和廣播了解起來有點抽象,我們還是舉個栗子來說明一下吧。

**例題 ** a 和 b 是等長的兩個整數數組,求 a 和 b 對應元素之積組成的數組。

1.用 python 數組實作:

c= list

fori inrange(len(a)):

c.append(a[i]*b[i])

用 numpy 數組實作:

c= a*b

這個栗子是不是展現了矢量化和廣播的強大力量呢?請仔細體會!

矢量化代碼更 pythonic

2. dtype AND shape

子曰:找對象先了解品行,學對象先了解屬性。 ndarray 對象有很多屬性,詳見下表。

屬性說明

ndarray.dtype元素類型

ndarray.shape數組的結構

ndarray.ndim秩,即軸的數量或次元的數量

ndarray.size數組元素的個數

ndarray.itemsize每個元素的大小,以位元組為機關

ndarray.flags數組的記憶體資訊

ndarray.real元素的實部

ndarray.imag元素的虛部

ndarray.data數組元素的實際存儲區

基于以下三個原因,我認為,dtype 和 shape 是 ndarray 最重要的兩個屬性,重要到幾乎可以忽略其他的屬性。

我們趟過的坑,幾乎都是 dtype 挖的

我們的迷茫,幾乎都是因為 shape 和我們期望的不一樣

我們的工作,很多都是在改變 shape

ndarray.astype 可以修改元素類型, ndarray.reshape 可以重新定義數組的結構,這兩個方法的重要性和其對應的屬性一樣。記住這兩個屬性和對應的兩個方法,就算是登堂入室了。想了解 numpy 支援的元素類型,請點選《數學模組化三劍客MSN》

3. 建立數組

(1) 建立簡單數組

numpy.array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)

numpy.empty(shape, dtype=float, order='C')

numpy.zeros(shape, dtype=float, order='C')

numpy.ones(shape, dtype=float, order='C')

numpy.eye(N, M=None, k=0, dtype=float, order='C')

>>> importnumpyasnp

>>>> np.array([1, 2, 3])

array([1, 2, 3])

>>> np.empty((2, 3))

array([[2.12199579e-314, 6.36598737e-314, 1.06099790e-313],

[1.48539705e-313, 1.90979621e-313, 2.33419537e-313]])

>>> np.zeros(2)

array([0., 0.])

>>> np.ones(2)

array([1., 1.])

>>> np.eye(3)

array([[1., 0., 0.],

[0., 1., 0.],

[0., 0., 1.]])

(2) 建立随機數組

numpy.random.random(size=None)

numpy.random.randint(low, high=None, size=None, dtype='l')

>>> np.random.random(3)

array([0.29334156, 0.45858765, 0.99297047])

>>> np.random.randint(2, size=10)

array([1, 0, 0, 0, 1, 1, 0, 0, 1, 0])

>>> np.random.randint(5, size=(2, 4))

array([[4, 0, 2, 1],

[3, 2, 2, 0]])

>>> np.random.randint(3,10,(2,4))

array([[4, 8, 9, 6],

[7, 7, 7, 9]])

(3) 在數值範圍内建立數組

numpy.arange(start, stop, step, dtype=None)

numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)

>>> np.arange(5)

array([0, 1, 2, 3, 4])

>>> np.arange(0,5,2)

array([0, 2, 4])

>>> np.linspace(0, 5, 5)

array([0. , 1.25, 2.5, 3.75, 5. ])

>>> np.linspace(0, 5, 5, endpoint=False)

array([0., 1., 2., 3., 4.])

>>> np.logspace(1,3,3)

array([ 10., 100., 1000.])

>>> np.logspace(1, 3, 3, endpoint=False)

array([ 10. , 46.41588834, 215.443469])

(4) 從已有數組建立數組

numpy.asarray(a, dtype=None, order=None)

numpy.empty_like(a, dtype=None, order='K', subok=True)

numpy.zeros_like(a, dtype=None, order='K', subok=True)

numpy.ones_like(a, dtype=None, order='K', subok=True)[source]

>>> np.asarray([1,2,3])

array([1, 2, 3])

>>> np.empty_like(np.asarray([1,2,3]))

array([0, 0, 0])

>>> np.zeros_like(np.asarray([1,2,3]))

array([0, 0, 0])

>>> np.ones_like(np.asarray([1,2,3]))

array([1, 1, 1])

(5) 構造複雜數組

[1] 重複數組 tile

>>> a = np.arange(3)

>>> a

array([0, 1, 2])

>>> np.tile(a, 2)

array([0, 1, 2, 0, 1, 2])

>>> np.tile(a, (2,3))

array([[0, 1, 2, 0, 1, 2, 0, 1, 2],

[0, 1, 2, 0, 1, 2, 0, 1, 2]])

[2] 重複元素 repeat

>>> a = np.arange(3)

>>> a

array([0, 1, 2])

>>> a.repeat(2)

array([0, 0, 1, 1, 2, 2])

[3] 一維數組網格化: meshgrid

>>> lon = np.arange(30, 120, 10)

>>> lon

array([ 30, 40, 50, 60, 70, 80, 90, 100, 110])

>>> lat = np.arange(10, 50, 10)

>>> lat

array([10, 20, 30, 40])

>>> lons, lats = np.meshgrid(lon, lat)

>>> lons

array([[ 30, 40, 50, 60, 70, 80, 90, 100, 110],

[ 30, 40, 50, 60, 70, 80, 90, 100, 110],

[ 30, 40, 50, 60, 70, 80, 90, 100, 110],

[ 30, 40, 50, 60, 70, 80, 90, 100, 110]])

>>> lats

array([[10, 10, 10, 10, 10, 10, 10, 10, 10],

[20, 20, 20, 20, 20, 20, 20, 20, 20],

[30, 30, 30, 30, 30, 30, 30, 30, 30],

[40, 40, 40, 40, 40, 40, 40, 40, 40]])

[4] 指定範圍和分割方式的網格化: mgrid

>>> lats, lons= np.mgrid[10:50:10, 30:120:10]

>>> lats

array([[10, 10, 10, 10, 10, 10, 10, 10, 10],

[20, 20, 20, 20, 20, 20, 20, 20, 20],

[30, 30, 30, 30, 30, 30, 30, 30, 30],

[40, 40, 40, 40, 40, 40, 40, 40, 40]])

>>> lons

array([[ 30, 40, 50, 60, 70, 80, 90, 100, 110],

[ 30, 40, 50, 60, 70, 80, 90, 100, 110],

[ 30, 40, 50, 60, 70, 80, 90, 100, 110],

[ 30, 40, 50, 60, 70, 80, 90, 100, 110]])

>>> lats, lons = np.mgrid[10:50:5j, 30:120:10j]

>>> lats

array([[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],

[20., 20., 20., 20., 20., 20., 20., 20., 20., 20.],

[30., 30., 30., 30., 30., 30., 30., 30., 30., 30.],

[40., 40., 40., 40., 40., 40., 40., 40., 40., 40.],

[50., 50., 50., 50., 50., 50., 50., 50., 50., 50.]])

>>> lons

array([[ 30., 40., 50., 60., 70., 80., 90., 100., 110., 120.],

[ 30., 40., 50., 60., 70., 80., 90., 100., 110., 120.],

[ 30., 40., 50., 60., 70., 80., 90., 100., 110., 120.],

[ 30., 40., 50., 60., 70., 80., 90., 100., 110., 120.],

[ 30., 40., 50., 60., 70., 80., 90., 100., 110., 120.]])

上面的例子中用到了虛數。構造複數的方法如下:

>>> complex(2,5)

(2+5j)

1

2

4. 數組操作

(1) 切片和索引

對于一維數組的索引和切片,numpy和python的list一樣,甚至更靈活。

a = np.arange(9)

>>> a[-1] # 最後一個元素

8

>>> a[2:5] # 傳回第2到第5個元素

array([2, 3, 4])

>>> a[:7:3] # 傳回第0到第7個元素,步長為3

array([0, 3, 6])

>>> a[::-1] # 傳回逆序的數組

array([8, 7, 6, 5, 4, 3, 2, 1, 0])

假設有一棟2層樓,每層樓内的房間都是3行4列,那我們可以用一個三維數組來儲存每個房間的居住人數(當然,也可以是房間面積等其他數值資訊)。

>>> a = np.arange(24).reshape(2,3,4) # 2層3行4列

>>> a

array([[[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11]],

[[12, 13, 14, 15],

[16, 17, 18, 19],

[20, 21, 22, 23]]])>>> a[1][2][3] # 雖然可以這樣

23>>> a[1,2,3] # 但這才是規範的用法23>>> a[:,0,0] # 所有樓層的第1排第1列array([ 0, 12])

>>> a[0,:,:] # 1樓的所有房間,等價與a[0]或a[0,...]array([[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11]])

>>> a[:,:,1:3] # 所有樓層所有排的第2到4列

array([[[ 1, 2],[ 5, 6],[ 9, 10]],

[[13, 14],[17, 18],[21, 22]]])

>>> a[1,:,-1] # 2層每一排的最後一個房間array([15, 19, 23])

提示:對多元數組切片或索引得到的結果,次元不是确定的。

(2) 改變數組的結構

numpy 數組的存儲順序和數組的次元是不相幹的,是以改變數組的次元是非常便捷的操作,除 resize 外,這一類操作不會改變所操作的數組本身的存儲順序。>>> a = np.array([[1,2,3],[4,5,6]])>>> a.shape # 檢視數組次元

(2, 3)

>>> a.reshape(3,2) # 傳回3行2列的數組

array([[1, 2],

[3, 4],

[5, 6]])

>>> a.ravel # 傳回一維數組

array([1, 2, 3, 4, 5, 6])

>>> a.transpose # 行變列(類似于矩陣轉置)

array([[1, 4],

[2, 5],

[3, 6]])

>>> a.resize((3,2)) # 類似于reshape,但會改變所操作的數組

>>> aarray([[1, 2],

[3, 4],

[5, 6]])

np.rollaxis 用于改變軸的順序,傳回一個新的數組。用法如下:

numpy.rollaxis(a, axis, start=0)

a: 數組

axis: 要改變的軸。其他軸的相對順序保持不變

start: 要改變的軸滾動至此位置之前。預設值為0

>>> a = np.ones((3,4,5,6))>>> np.rollaxis(a, 3, 1).shape(3, 6, 4, 5)>>> np.rollaxis(a, 2).shape(5, 3, 4, 6)>>> np.rollaxis(a, 1, 4).shape(3, 5, 6, 4)

(3) 數組合并

[1] append

對于剛剛上手 numpy 的程式員來說,最大的困惑就是不能使用 append 方法向數組内添加元素了,甚至連 append 方法都找不到了。其實,numpy 仍然保留了 append 方法,隻不過這個方法不再是 numpy 數組的方法,而是是更新到最外層的 numpy 命名空間了,并且該方法的功能不再是追加元素,而是合并數組了。

>>> np.append([1, 2, 3], [[4, 5, 6], [7, 8, 9]])array([1, 2, 3, 4, 5, 6, 7, 8, 9])>>> np.append([[1, 2, 3]], [[4, 5, 6]], axis=0)array([[1, 2, 3],[4, 5, 6]])>>> np.append(np.array([[1, 2, 3]]), np.array([[4, 5, 6]]), axis=1)array([[1, 2, 3, 4, 5, 6]])

[2] concatenate

concatenate 和 append 的用法非常類似,不過是把兩個合并對象寫成了一個元組 。

>>> a = np.array([[1, 2], [3, 4]])>>> b = np.array([[5, 6]])>>> np.concatenate((a, b), axis=0)array([[1, 2],[3, 4],

[5, 6]])>>> np.concatenate((a, b.T), axis=1)array([[1, 2, 5],

[3, 4, 6]])>>> np.concatenate((a, b), axis=None)array([1, 2, 3, 4, 5, 6])

[3] stack

除了 append 和 concatenate ,數組合并還有更直接的水準合并(hstack)、垂直合并(vstack)、深度合并(dstack)等方式。假如你比我還懶,那就隻用 stack 吧,足夠了。

>>> a = np.arange(9).reshape(3,3)>>> b = np.arange(9,18).reshape(3,3)

>>> a

array([[0, 1, 2],

[3, 4, 5],

[6, 7, 8]])

>>> b

array([[ 9, 10, 11],

[12, 13, 14],

[15, 16, 17]])

>>> np.hstack((a,b)) # 水準合并

array([[ 0, 1, 2, 9, 10, 11],

[ 3, 4, 5, 12, 13, 14],

[ 6, 7, 8, 15, 16, 17]])

>>> np.vstack((a,b)) # 垂直合并

array([[ 0, 1, 2],

[ 3, 4, 5],

[ 6, 7, 8],

[ 9, 10, 11],

[12, 13, 14],

[15, 16, 17]])

>>> np.dstack((a,b)) # 深度合并

array([[[ 0, 9],

[ 1, 10],

[ 2, 11]],

[[ 3, 12],

[ 4, 13],

[ 5, 14]],

[[ 6, 15],

[ 7, 16],

[ 8, 17]]])

(4) 數組拆分

>>> a = np.arange(4).reshape(2,2)>>> a

array([[0, 1],

[2, 3]])

>>> x, y = np.hsplit(a, 2) # 水準拆分,傳回list

>>> x

array([[0],

[2]])

>>> y

array([[1],

[3]])

>>> x, y = np.vsplit(a, 2) # 垂直拆分,傳回list

>>> x

array([[0, 1]])

>>> y

array([[2, 3]])

>>> a = np.arange(8).reshape(2,2,2)

>>> a

array([[[0, 1],

[2, 3]],

[[4, 5],

[6, 7]]])

>>> x,y = np.dsplit(a, 2) # 深度拆分,傳回list

>>> x

array([[[0],

[2]],

[[4],

[6]]])

>>> y

array([[[1],

[3]],

[[5],

[7]]])

(5) 數組排序

排序不是 numpy 數組的強項,但 python 數組的排序速度依然隻能望其項背。

[1] numpy.sort

numpy.sort 函數傳回輸入數組的排序副本。

numpy.sort(a, axis=-1, kind='quicksort', order=None)

a: 要排序的數組

axis: 沿着它排序數組的軸,如果沒有,數組會被展開,沿着最後的軸排序

kind: 排序方法,預設為’quicksort’(快速排序),其他選項還有 ‘mergesort’(歸并排序)和 ‘heapsort’(堆排序)

order: 如果數組包含字段,則是要排序的字段

>>> a = np.array([3, 1, 2])>>> np.sort(a)

array([1, 2, 3])

>>> dt = np.dtype([('name', 'S10'),('age', int)])

>>> a = np.array([("raju",21),("anil",25),("ravi", 17), ("amar",27)], dtype = dt)

>>> a

array([(b'raju', 21), (b'anil', 25), (b'ravi', 17), (b'amar', 27)],

dtype=[('name', 'S10'), ('age', '

>>> np.sort(a, order='name')

array([(b'amar', 27), (b'anil', 25), (b'raju', 21), (b'ravi', 17)],

dtype=[('name', 'S10'), ('age', '

[2] numpy.argsort

numpy.argsort(a, axis=-1, kind='quicksort', order=None)

a: 要排序的數組

axis: 沿着它排序數組的軸,如果沒有,數組會被展開,沿着最後的軸排序

kind: 排序方法,預設為’quicksort’(快速排序),其他選項還有 ‘mergesort’(歸并排序)和 ‘heapsort’(堆排序)

order: 如果數組包含字段,則是要排序的字段

>>> a = np.array([3, 1, 2])>>> np.argsort(a)array([1, 2, 0], dtype=int64)

(6) 查找和篩選

[1] 傳回數組中最大值和最小值的索引

numpy.argmax(a, axis=None, out=None)numpy.argmin(a, axis=None, out=None)

[2] 傳回數組中非零元素的索引

numpy.nonzero(a)

[3] 傳回數組中滿足給定條件的元素的索引

numpy.where(condition[, x, y])

>>> a = np.arange(10)>>> aarray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>> np.where(a < 5)(array([0, 1, 2, 3, 4], dtype=int64),)>>> a = a.reshape((2, -1))>>> aarray([[0, 1, 2, 3, 4],[5, 6, 7, 8, 9]])>>> np.where(a < 5)(array([0, 0, 0, 0, 0], dtype=int64), array([0, 1, 2, 3, 4], dtype=int64))>>> np.where(a < 5, a, 10*a)array([[ 0, 1, 2, 3, 4],[50, 60, 70, 80, 90]])

[4] 傳回數組中被同結構布爾數組選中的各元素

numpy.extract(condition, arr)

>>>a = np.arange(12).reshape((3, 4))>>>a

array([[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11]])

>>>condition = np.mod(a, 3)==0

>>>condition

array([[ True, False, False, True],

[False, False, True, False],

[False, True, False, False]])

>>>np.extract(condition, a)

array([0, 3, 6, 9])

(7) 增減元素

[1] 在給定索引之前沿給定軸在輸入數組中插入值,并傳回新的數組

numpy.insert(arr, obj, values, axis=None)

>>> a = np.array([[1, 1], [2, 2], [3, 3]])>>> a

array([[1, 1],

[2, 2],

[3, 3]])

>>> np.insert(a, 1, 5)

array([1, 5, 1, 2, 2, 3, 3])

>>> np.insert(a, 1, 5, axis=0)

array([[1, 1],

[5, 5],

[2, 2],

[3, 3]])

>>> np.insert(a, 1, [5,7], axis=0)

array([[1, 1],

[5, 7],

[2, 2],

[3, 3]])

>>> np.insert(a, 1, 5, axis=1)

array([[1, 5, 1],

[2, 5, 2],

[3, 5, 3]])

[2] 在給定索引之前沿給定軸删除指定子數組,并傳回新的數組

numpy.delete(arr, obj, axis=None)

>>> a = np.array([[1, 2], [3, 4], [5, 6]])>>> a

array([[1, 2],

[3, 4],

[5, 6]])

>>> np.delete(a, 1)

array([1, 3, 4, 5, 6])

>>> np.delete(a, 1, axis=0)

array([[1, 2],

[5, 6]])

>>> np.delete(a, 1, axis=1)

array([[1],

[3],

[5]])

[3] 去除重複元素

numpy.unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None)

arr:輸入數組,如果不是一維數組則會展開

return_index:如果為true,傳回新清單元素在舊清單中的位置(下标),并以清單形式儲

return_inverse:如果為true,傳回舊清單元素在新清單中的位置(下标),并以清單形式儲

return_counts:如果為true,傳回去重數組中的元素在原數組中的出現次數

>>> a = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]])>>> np.unique(a)

array([0, 1, 2, 3, 4])

>>> np.unique(a, axis=0)

array([[1, 0, 0],

[2, 3, 4]])

>>> u, indices = np.unique(a, return_index=True)

>>> u

array([0, 1, 2, 3, 4])

>>> indices

array([1, 0, 6, 7, 8], dtype=int64)

>>> u, indices = np.unique(a, return_inverse=True)

>>> u

array([0, 1, 2, 3, 4])

>>> indices

array([1, 0, 0, 1, 0, 0, 2, 3, 4], dtype=int64)

>>> u, num = np.unique(a, return_counts=True)

>>> u

array([0, 1, 2, 3, 4])

>>> num

array([4, 2, 1, 1, 1], dtype=int64)

(8) 數組IO

numpy 為 ndarray 對象引入了新的二進制檔案格式,用于存儲重建 ndarray 所需的資料、圖形、dtype 和其他資訊。.npy 檔案存儲單個數組,.npz 檔案存取多個數組。

[1] 儲存單個數組到檔案

numpy.save(file, arr, allow_pickle=True, fix_imports=True)

file: 要儲存的檔案,擴充名為 .npy,如果檔案路徑末尾沒有擴充名 .npy,該擴充名會被自動加上

arr: 要儲存的數組

allow_pickle: 可選,布爾值,允許使用 python pickles 儲存對象數組,python 中的 pickle 用于在儲存到磁盤檔案或從磁盤檔案讀取之前,對對象進行序列化和反序列化

fix_imports: 可選,為了友善 pyhton2 讀取 python3 儲存的資料

[2] 儲存多個數組到檔案

numpy.savze 函數用于将多個數組寫入檔案,預設情況下,數組是以未壓縮的原始二進制格式儲存在擴充名為 .npz 的檔案中。

numpy.savez(file, *args, **kwds)

file: 要儲存的檔案,擴充名為 .npz,如果檔案路徑末尾沒有擴充名 .npz,該擴充名會被自動加上

args: 要儲存的數組,可以使用關鍵字參數為數組起一個名字,非關鍵字參數傳遞的數組會自動起名為 arr_0, arr_1, …

kwds: 要儲存的數組使用關鍵字名稱

[3] 從檔案加載數組

numpy.load(file, mmap_mode=None, allow_pickle=True, fix_imports=True, encoding='ASCII')

file: 類檔案對象(支援 seek 和 read方法)或者要讀取的檔案路徑

arr: 打開方式,None | ‘r+’ | ‘r’ | ‘w+’ | ‘c’

allow_pickle: 可選,布爾值,允許使用 python pickles 儲存對象數組,python 中的 pickle 用于在儲存到磁盤檔案或從磁盤檔案讀取之前,對對象進行序列化和反序列化

fix_imports: 可選,為了友善 pyhton2 讀取 python3 儲存的資料

encoding: 編碼格式,‘latin1’ | ‘ASCII’ | ‘bytes’

a = np.array([[1,2,3],[4,5,6]])b = np.arange(0, 1.0, 0.1)

c = np.sin(b)

# c 使用了關鍵字參數 sin_array

np.savez("runoob.npz", a, b, sin_array = c)

r = np.load("runoob.npz")

print(r.files) # 檢視各個數組名稱

print(r["arr_0"]) # 數組 a

print(r["arr_1"]) # 數組 b

print(r["sin_array"]) # 數組 c

[4] 使用文本檔案存取數組

numpy 也支援以文本檔案存取資料。savetxt 函數是以簡單的文本檔案格式存儲資料,對應的使用 loadtxt 函數來擷取資料。

a = np.array([1,2,3,4,5])np.savetxt('out.txt',a)b = np.loadtxt('out.txt')print(b)

5. 常用函數

(1) 舍入函數

[1] 四舍五入

numpy.around(a, decimals=0, out=None)

>>> np.around([-0.42, -1.68, 0.37, 1.64])

array([-0., -2., 0., 2.])

>>> np.around([-0.42, -1.68, 0.37, 1.64], decimals=1)

array([-0.4, -1.7, 0.4, 1.6])

>>> np.around([.5, 1.5, 2.5, 3.5, 4.5]) # rounds to nearest even value

array([ 0., 2., 2., 4., 4.])

[2] 去尾和進一

numpy.floor(a)numpy.ceil(a)

>>> np.floor([-0.42, -1.68, 0.37, 1.64])array([-1., -2., 0., 1.])

>>> np.ceil([-0.42, -1.68, 0.37, 1.64])

array([-0., -1., 1., 2.])

(2) 數學函數

函數說明

numpy.deg2rad / numpy.radians度轉弧度

numpy.rad2deg / numpy.degrees弧度轉度

numpy.sin正弦函數

numpy.arcsin反正弦函數

numpy.cos餘弦函數

numpy.arccos反餘弦函數

numpy.tan正切函數

numpy.arctan反正切函數

numpy.hypot計算直角三角形斜邊

numpy.square平方

numpy.sqrt開平方

numpy.power乘方

numpy.exp指數

numpy.log對數

numpy.log2對數

numpy.log10對數

(3) 統計函數

函數說明

numpy.sum(a[, axis, dtype, out, keepdims])按指定的軸求元素之和

numpy.nansum(a[, axis, dtype, out, keepdims])按指定的軸求元素之和,numpy.nan視為0

numpy.cumsum(a[, axis, dtype, out])按指定的軸求元素累進和

numpy.prod(a[, axis, dtype, out, keepdims])按指定的軸求元素之積

numpy.diff(a[, n, axis])傳回相鄰元素的差

numpy.ptp傳回數組中元素最大值與最小值的差

numpy.var傳回數組方差

numpy.std傳回數組标準差

numpy.median傳回數組元素的中位數

numpy.mean(a, axis=None, dtype=None, out=None, keepdims=)傳回所有元素的算數平均值

numpy.average根據權重資料,傳回資料數組所有元素的夾權平均值

6. 牛刀小試

**例題 ** vertices 是若幹三維空間随機點的集合,p 是三維空間的一點,找出 vertices 中距離 p 點最近的一個點,并計算它們的距離。

用 python 數組實作:

importmathvertices = [[3,4,5], [7,8,9], [4,9,3]]

p = [2,7,4]

d = list

forv in vertices:

d.append(math.sqrt(math.pow(v[0]-p[0], 2)+math.pow(v[1]-p[1], 2)+math.pow(v[2]-p[2], 2)))

print(vertices[d.index(min(d))], min(d))

用 numpy 數組實作:

import numpy as np

vertices = np.array([[3,4,5], [7,8,9], [4,9,3]])

p = np.array([2,7,4])

d = np.sqrt(np.sum(np.square((vertices-p)), axis=1))

print(vertices[d.argmin], d.min)

用随機方式生成1000個點,比較兩種的方法的效率。

【本文作者】

許向武:山東遠思資訊科技有限公司CEO,網名牧碼人(天元浪子),齊國土著,太公之後。少小離家,獨闖江湖,後歸隐于華不注山。素以敲擊鍵盤為業,偶爾遊戲于各網絡對局室,擅長送财送分,深為衆棋友所喜聞樂見。傳回搜狐,檢視更多

責任編輯: