不懂NumPy 算什麼 Python 程式設計師?|CSDN 博文精選

2021-01-07 CSDN

作者 | 天元浪子

責編 | 郭芮

出品 | CSDN 博客

大約七八年前,我曾經用 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 程式設計師。

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()for i in range(len(a)): c.append(a[i]*b[i])

2、用 numpy 數組實現:

c = a*b

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

總結:

矢量化代碼更簡潔,更易於閱讀;更少的代碼行通常意味著更少的錯誤;代碼更接近於標準的數學符號;矢量化代碼更 pythonic。

dtype AND shape

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

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

我們趟過的坑,幾乎都是 dtype 挖的;我們的迷茫,幾乎都是因為 shape 和我們期望的不一樣;我們的工作,很多都是在改變 shape。ndarray.astype() 可以修改元素類型,ndarray.reshape() 可以重新定義數組的結構,這兩個方法的重要性和其對應的屬性一樣。記住這兩個屬性和對應的兩個方法,就算是登堂入室了。想了解 numpy 支持的元素類型,請點擊《數學建模三劍客MSN》(https://blog.csdn.net/xufive/article/details/52449255)。

創建數組

(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)>>> aarray([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)>>> aarray([0, 1, 2])>>> a.repeat(2)array([0, 0, 1, 1, 2, 2])

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

>>> lon = np.arange(30, 120, 10)>>> lonarray([ 30, 40, 50, 60, 70, 80, 90, 100, 110])>>> lat = np.arange(10, 50, 10)>>> latarray([10, 20, 30, 40])>>> lons, lats = np.meshgrid(lon, lat)>>> lonsarray([[ 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]])>>> latsarray([[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]])>>> lonsarray([[ 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]>>> latsarray([[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.]])>>> lonsarray([[ 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) 切片和索引

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

a = np.arange(9)>>> a[-1] # 最後一個元素8>>> a[2:5] # 返回第2到第5個元素array([2, 3, 4])>>> a[:7:3] # 返回第0到第7個元素,步長為3array([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列>>> aarray([[[ 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)>>> aarray([[0, 1, 2], [3, 4, 5], [6, 7, 8]])>>> barray([[ 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]]])

stack 函數原型為 stack(arrays, axis=0),請注意體會下面例子中的 axis 的用法。

>>> a = np.arange(60).reshape(3,4,5)>>> b = np.arange(60).reshape(3,4,5)>>> a.shape, b.shape((3, 4, 5), (3, 4, 5))>>> np.stack((a,b), axis=0).shape(2, 3, 4, 5)>>> np.stack((a,b), axis=1).shape(3, 2, 4, 5)>>> np.stack((a,b), axis=2).shape(3, 4, 2, 5)>>> np.stack((a,b), axis=3).shape(3, 4, 5, 2)

(4) 數組拆分

拆分是合併的逆過程,概念是一樣的,但稍微有一點不同:

>>> a = np.arange(4).reshape(2,2)>>> aarray([[0, 1], [2, 3]])>>> x, y = np.hsplit(a, 2) # 水平拆分,返回list>>> xarray([[0], [2]])>>> yarray([[1], [3]])>>> x, y = np.vsplit(a, 2) # 垂直拆分,返回list>>> xarray([[0, 1]])>>> yarray([[2, 3]])>>> a = np.arange(8).reshape(2,2,2)>>> aarray([[[0, 1], [2, 3]],[[4, 5], [6, 7]]])>>> x,y = np.dsplit(a, 2) # 深度拆分,返回list>>> xarray([[[0], [2]],[[4], [6]]])>>> yarray([[[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)>>> aarray([(b'raju', 21), (b'anil', 25), (b'ravi', 17), (b'amar', 27)], dtype=[('name', 'S10'), ('age', '<i4')])>>> np.sort(a, order='name')array([(b'amar', 27), (b'anil', 25), (b'raju', 21), (b'ravi', 17)], dtype=[('name', 'S10'), ('age', '<i4')])

[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))>>> aarray([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])>>> condition = np.mod(a, 3)==0>>> conditionarray([[ 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]])>>> aarray([[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]])>>> aarray([[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)>>> uarray([0, 1, 2, 3, 4])>>> indicesarray([1, 0, 6, 7, 8], dtype=int64)>>> u, indices = np.unique(a, return_inverse=True)>>> uarray([0, 1, 2, 3, 4])>>> indicesarray([1, 0, 0, 1, 0, 0, 2, 3, 4], dtype=int64)>>> u, num = np.unique(a, return_counts=True)>>> uarray([0, 1, 2, 3, 4])>>> numarray([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_arraynp.savez("runoob.npz", a, b, sin_array = c)r = np.load("runoob.npz") print(r.files) # 查看各個數組名稱print(r["arr_0"]) # 數組 aprint(r["arr_1"]) # 數組 bprint(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)

常用函數

(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 valuearray([ 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) 數學函數

(3) 統計函數

牛刀小試

例題:vertices 是若干三維空間隨機點的集合,p 是三維空間的一點,找出 vertices 中距離 p 點最近的一個點,並計算它們的距離。

1、用 python 數組實現:

import mathvertices = [[3,4,5], [7,8,9], [4,9,3]]p = [2,7,4]d = list()for v 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))

2、用 numpy 數組實現:

import numpy as npvertices = 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個點,比較兩種方法的效率。

相關焦點

  • 一行Python 代碼能實現什麼喪心病狂的功能?|CSDN博文精選
    這個數據結構,自然是 numpy 的 ndarray 對象,讀取圖像文件我習慣使用 PIL。因此,需要導入兩個模塊:import numpy as npfrom PIL import Image接下來,我用一行代碼就把 109 張圖片讀到了一個 109x256x256x4 的 numpy 數組中,耗時 172 毫秒:data = np.stack([np.array(Image.open('head%d.png'%i)) for i in range
  • 如果不懂Numpy,請別說自己是Python程式設計師
    在那之前,我一直覺得自己是一個合(you)格(xiu)的 python 程式設計師,似乎無所不能。但磁層頂模型的顯示效果令我沮喪——儘管這個模型只有十幾萬個頂點,拖拽、縮放卻非常卡頓。最終,我把頂點數量刪減到兩萬左右,以兼顧模型質量和響應速度,才勉強交付了這個任務。從此我開始懷疑 python 的性能,甚至一度懷疑 python 是否還是我的首選工具。
  • 好程式設計師Python培訓分享numpy簡介
    好程式設計師Python培訓分享numpy簡介:一、numpy簡介:NumPy是一個功能強大的Python庫,主要用於對多維數組執行計算。NumPy這個詞來源於兩個單詞-- Numerical和Python。NumPy提供了大量的庫函數和操作,可以幫助程式設計師輕鬆地進行數值計算。
  • |CSDN 博文精選
    關於 wxPython我一直認為,wxPython 是最適合 Python 的GUI庫,並為此專門寫過一篇博文。詳情見《wxPython:Python首選的GUI庫》。這裡不再討論如何使用 wxPython,只貼出幾張開發項目的截圖,展示一下 wxPython 的風格。
  • Python的武器庫05:numpy模塊(下)
    說到程式語言python,有一個著名的格言"餘生太短,只用python"。如果要分析為什麼會存在這麼一句格言?python的語法並不簡單,有複雜難懂的部分,之所以有這樣一句格言,是因為python中有很多強大的模塊,就像一個武器庫。
  • 計算機大數乘法引發的思考 | CSDN 博文精選
    我們當然希望設計一種巧算的步驟,但在此之前,我們先設計一種 按部就班的算法,類似我們手算豎式一樣:人就是這麼算的,老老實實地按照十進位99乘法表,一個數字一個數字地進行計算,計算過程中處理進位。手工算豎式人人都會,說這些也無益,上周三下班的班車上,順手擼了一個代碼,感覺還好,發了個朋友圈就想分享出來,本周就休息一天,趕早起來就寫下了這篇文章。
  • Python的武器庫04:numpy模塊(上)
    說到程式語言python,有一個著名的格言"餘生太短,只用python"。如果要分析為什麼會存在這麼一句格言?python的語法並不簡單,有複雜難懂的部分,之所以又這樣一句格言,是因為python中有很多強大的模塊,就像一個武器庫。Python正式由於這些模塊的出現,只要引入這個模塊,調用這個模塊的集成函數,問題迎刃而解;不需要從頭開始,節省了大量的時間。
  • Python學習第119課——numpy中的broadcasting
    【每天幾分鐘,從零入門python編程的世界!】這節課我們學習numpy中的數據的一個多變的特性--broadcasting,broadcasting的官方的說明比較麻煩,我們這裡把它簡化一下,就把它當做「腦補」的意思。我們舉例來說明。
  • Python學習第114課——numpy中ndarray的四則運算
    【每天幾分鐘,從零入門python編程的世界!】我們為什麼要學習numpy?numpy其實就是number+Python的簡寫,意思就是通過Python對數據進行處理。要對數據進行處理,就少不了最基本的加減乘除等操作。
  • Python NumPy用法介紹
    使用下面格式約定,引入NumPy包:import numpy as npNumPy的ndarray:N維數組對象NumPy最重要的是其N維數組對象(即ndarray),其中的所有元素必須是相同類型的。但修改原數組(維度變換).swapaxes(ax1,ax2) 將數組n個維度中兩個維度進行調換(維度變換).flatten():對數組進行降維,返回摺疊後的一維數組,原數組不變(維度變換).tolist():將N維數組轉換成列表(維度變換)ndarray數組的索引和切片具體使用參考https://seancheney.gitbook.io/python-for-data-analysis
  • 計算機大數乘法引發的思考|CSDN 博文精選
    我們當然希望設計一種巧算的步驟,但在此之前,我們先設計一種 按部就班的算法,類似我們手算豎式一樣:人就是這麼算的,老老實實地按照十進位99乘法表,一個數字一個數字地進行計算,計算過程中處理進位。手工算豎式人人都會,說這些也無益,上周三下班的班車上,順手擼了一個代碼,感覺還好,發了個朋友圈就想分享出來,本周就休息一天,趕早起來就寫下了這篇文章。
  • python數據科學系列:numpy入門詳細教程
    轉自:小數志pyth
  • 《Python程式設計師面試算法寶典》PDF超清版開源了文末附下載方式
    簡介精選Facebook、Google、Microsoft和BAT等大型企業的Python算法面試題,並進行詳細的剖析、分類歸納,提煉出算法面試的各種應對技巧,是一本Python程式設計師算法面試的圖書寶典。
  • Python學習第117課——numpy中dot的運用舉例
    【每天幾分鐘,從零入門python編程的世界!】上節我們學習了最基礎的matrix的運算,可能有小夥伴覺得這都要涉及高等數學知識了,確實如果你想做數據科學、做人工智慧,統計學、概率論等數學知識,尤其是算法是繞不過去的坎,但是不要怕!!!
  • |CSDN 博文精選
    | CSDN 博文精選40 歲編程經驗 30 年!支付寶資深工程師的程序人生Linux 給我的七個寶貴教訓揭秘 OceanBase 勇奪 TPC 榜首的王者攻略!搞開發沒加薪、也沒升職?都被你浪沒了!
  • Python程式設計師必備——Numpy 100題(附答案)
    1.Import the numpy package under the name np (★☆☆)import numpy as np2.Print the numpy version and the configuration (★☆☆)print(np.
  • Python中的Numpy基礎20問
    import numpy as np# 創建二維數組x2 = np.array([[1,2,3],[4,5,6]])# 將x2轉換為三維數組,並且自定義每個軸的元素數量x2.resize((1,2,3))x2'''輸出:array([[[1, 2, 3],[4, 5, 6]]])'''如何對數組進行索引和切片操作?numpy一維數組的索引和切片操作類似python列表,這裡不多講。
  • Python學習第113課——numpy中用條件判斷去篩選數組中的元素
    【每天幾分鐘,從零入門python編程的世界!】之前我們學習了如何在numpy中查找數組元素的方法和技巧,現在我們學習如何用條件判斷的方式篩選數組的元素。●numpy中的數組可以直接進行比較直接上代碼:運行結果:我們看到,condition列印出來,它的結構和h的結構一樣。
  • 中科大統計學python_python 中科大 - CSDN
    6、Matplotlib Python 畫圖教程 (莫煩Python)https://www.bilibili.com/video/av16378354/課程介紹:Matplotlib 是一個非常強大的 Python 畫圖工具;這門課程可以對比莫煩numpy
  • Python:一篇文章掌握Numpy的基本用法
    This could mean that an intermediate result is being cached.1000 loops, best of 3: 128 µs per loop從上面的運行結果可以看出,numpy的向量化運算的效率要遠遠高於python的循環遍歷運算(效率相差好幾百倍)。