01.22 小貼士~這4個Numpy技巧送給初學Python的你

全文共3384字,預計學習時長

10分鐘

小貼士~這4個Numpy技巧送給初學Python的你

圖源:Unsplash


Python初學者除了要掌握基礎知識外,瞭解一些小技巧、小竅門也是學習路上必不可少的一種催化劑,能幫助你更好的學習。


Numpy作為Python最受歡迎的庫之一,鑑於其優勢,幾乎每個Python程序員都將其用於算術運算。Numpy數組比Python列表更緊湊。該庫還方便地以非常高效的計算方式實現了許多常見的矩陣運算。


下面小芯就基於實踐整理出了Python初學者應該學習的4個numpy技巧,它們能夠幫助你編寫更簡潔易讀的代碼。


在學習numpy技巧之前,請確保已熟悉以下文章中的一些Python內置功能。


1. 掩碼數組——選擇


數據集是不完善的,它們總是包含缺失或無效記錄的數組,而這些記錄是時常需要忽略的。例如,由於傳感器故障,氣象站的測量值可能包含缺失值。


Numpy有一個子模塊numpy.ma,它支持帶掩碼的數據數組。帶掩碼的數組包含一個普通的numpy數組和一個指示無效記錄位置的掩碼。

np.ma.MaskedArray(data=arr,mask=invalid_mask)

有時使用負值或字符串標記數組中的無效記錄。如果知道被掩蓋的值,例如-999,也可以使用np.ma.masked_values(arr,value = -999)創建一個掩碼數組。任何以掩碼數組為參數的numpy操作都會自動忽略這些無效記錄,如下所示。

import math

defis_prime(n):

assert n >1, 'Input must be larger than 1'

if n %2==0and n >2:

returnFalse

returnall(n % i for i inrange(3, int(math.sqrt(n)) +1, 2))

arr = np.array(range(2,100))

non_prime_mask = [not is_prime(n) for n in a]

prime_arr = np.ma.MaskedArray(data=arr, mask=non_prime_mask)

print(prime_arr)

# [2 3 -- 5 -- 7 -- -- -- 11 -- 13 -- --

-- 17 -- 19 -- -- -- 23 -- -- -- --

# -- 29 -- 31 -- -- -- -- -- 37 -- --

-- 41 -- 43 -- -- -- 47 -- -- -- --

# -- 53 -- -- -- -- -- 59 -- 61 -- --

-- -- -- 67 -- -- -- 71 -- 73 -- --

# -- -- -- 79 -- -- -- 83 -- -- -- --

-- 89 -- -- -- -- -- -- -- 97 -- --]

arr = np.array(range(11))

print(arr.sum()) # 55

arr[-1] =-999# indicates missing value

masked_arr = np.ma.masked_values(arr, -999)

print(masked_arr.sum()) # 45

查看由GitHub託管在❤的rawnumpy-ma.py


2. 廣播——形狀


小貼士~這4個Numpy技巧送給初學Python的你

圖源:Unsplash


廣播是一個numpy初學者可能會不經意嘗試過的事情。許多numpy算術運算都應用在具有相同形狀的數組對上,並對這些數組對的元素進行逐一操作。廣播可以向量化數組操作,而無需複製不必要的數據。這帶來了有效的算法實現和更高的代碼可讀性。


例如,可以使用arr + 1將數組中的所有值加1,而不考慮arr的維數。還可以通過arr > 2檢查數組中的所有值是否都大於2。


但是如何知道兩個數組是否與廣播兼容呢?

Argument 1 (4D array): 7× 5 × 3 × 1

Argument 2 (3D array): 1 × 3 × 9

Output (4D array): 7 × 5 × 3 × 9

兩個數組的每個維度必須相等,或者其中之一為1。它們不需要具有相同數量的維度。以上示例說明了這些規則。


3. Arg函數——位置


對於一個數組arr,np.argmax(arr),np.argmin(arr)以及np.argwhere(condition(arr))分別返回最大值,最小值以及滿足用戶定義條件的值的索引。儘管這些arg函數得到了廣泛使用,但我們經常忽略np.argsort()函數,它用於返回對數組進行排序的索引。


可以使用np.argsort根據另一個數組對數組的值進行排序。以下示例使用考試分數對學生姓名進行排序。也可以使用np.argsort(np.argsort(score))將排序後的姓名數組轉換回其原始順序。

score = np.array([70, 60, 50, 10, 90, 40, 80])

name = np.array(['Ada', 'Ben', 'Charlie', 'Danny',

'Eden', 'Fanny', 'George'])

sorted_name = name[np.argsort(score)]

# an array of names in ascending order of their scores

print(sorted_name)

# ['Danny' 'Fanny' 'Charlie' 'Ben' 'Ada' 'George' 'Eden']

original_name = sorted_name[np.argsort(np.argsort(score))]

print(original_name)

# ['Ada' 'Ben' 'Charlie' 'Danny' 'Eden' 'Fanny' 'George']

%timeit name[np.argsort(score)]

# 1.83 µs ± 182 ns per loop

(mean ± std. dev. of 7 runs, 100000 loops each)

%timeit sorted(zip(score, name))

# 3.2 µs ± 76.7 ns per loop

(mean ± std. dev. of 7 runs, 100000 loops each)

查看由GitHub託管在❤ 的rawnumpy-argsort.py

它的性能比使用內置的Python函數sorted(zip())快,並且可讀性更高。

4. 省略號和NewAxis——維度


小貼士~這4個Numpy技巧送給初學Python的你

圖源:Unsplash


分割numpy數組的語法為i:j,其中i,j分別代表起始索引和終止索引。對於一個numpy數組arr=np.array(range(10)),調用arr[:3]即返回[0,1,2]。

當處理高維數組時,可以使用: 來選擇每個軸的所有索引。還可以使用…選擇多個軸上的所有索引。由此可以推斷出擴展軸的確切數量。

arr = np.array(range(1000)).reshape(2,5,2,10,-1)

print(arr[:,:,:,3,2] == arr[...,3,2])

# [[[ True, True],

# [ True, True],

# [ True, True],

# [ True, True],

# [ True, True]],

# [[ True, True],

# [ True, True],

# [ True, True],

# [ True, True],

# [ True, True]]])

print(arr.shape) # (2, 5, 2, 10, 5)

print(arr[...,np.newaxis,:,:,:].shape) # (2, 5, 1, 2, 10, 5)

查看由GitHub託管在❤的rawnumpy-slicing.py

另一方面,如上所示使用np.newaxis在用戶定義的軸位置插入新軸。此操作將數組的形狀擴展了一個維度單位。儘管這也可以通過np.expand_dims()實現,但使用np.newaxis更具可讀性,並且更加優雅。


小貼士~這4個Numpy技巧送給初學Python的你

圖源:Unsplash


祝大家繼續開心敲代碼~一天更比一天強~

小貼士~這4個Numpy技巧送給初學Python的你

小貼士~這4個Numpy技巧送給初學Python的你

我們一起分享AI學習與發展的乾貨


分享到:


相關文章: