全文共3384字,預計學習時長
10分鐘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. 廣播——形狀
廣播是一個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——維度
分割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更具可讀性,並且更加優雅。
祝大家繼續開心敲代碼~一天更比一天強~
我們一起分享AI學習與發展的乾貨
閱讀更多 讀芯術 的文章