赚到!4个Python初学者必学的Numpy小技巧

 2020-01-22 17:01:00

全文共3384字,预计学习时长10分钟

赚到!4个Python初学者必学的Numpy小技巧_第1张图片

图源: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个Python初学者必学的Numpy小技巧_第2张图片

图源: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个Python初学者必学的Numpy小技巧_第3张图片

图源: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个Python初学者必学的Numpy小技巧_第4张图片

图源:Unsplash

 

祝大家继续开心敲代码~一天更比一天强~

你可能感兴趣的:(人工智能)