numpy小记

70个NumPy分级练习题:用Python一举搞定机器学习矩阵运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import numpy as np
# 1. 替换满足条件的元素而不影响原始数组
arr = np.arange(10)
out = np.where(arr%2==1, -1, arr)
arr
Out[4]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
out
Out[5]: array([ 0, -1, 2, -1, 4, -1, 6, -1, 8, -1])

# 7. 获取两个数组元素匹配的索引号
a = np.array([1,2,3,2,3,4,3,4,5,6])
b = np.array([7,2,10,2,7,4,9,4,9,8])
np.where(a==b)
Out[33]: (array([1, 3, 5, 7], dtype=int64),)

# 9. 将处理标量的python函数在numpy数组上运行
maxx = lambda x,y: x if x>=y else y
pair_max = np.vectorize(maxx, otypes=[float])
a = np.array([5,7,9,8,6,4,5])
b = np.array([6,3,4,8,9,7,1])
pair_max(a,b)
Out[45]: array([6., 7., 9., 8., 9., 7., 5.])

# 18. 导入含有数字和文本的数据集,并保持的文本完整性
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
irirs_ld = np.genfromtxt(url, delimiter=',', dtype=None)

# 21. 计算softmax值
def softmax(x):
ex = np.exp(x-np.max(x))
return ex/ex.sum(axis=0)

# 29. 概率抽样
# 暂定

# 33. 两个数组之间的欧氏距离
arr = np.arange(5)
brr = np.arange(4,9)
dist = np.linalg.norm(arr-brr)
dist
Out[176]: 8.94427190999916

# 38. 不连续的日期数组。通过填补缺失的日期,使其成为连续的日期序列
# 39. 一维数组arr,使用步长生成一个二维数组,窗口长度为4,步长为2
def gen_strides(arr, stride_len=5, windows_len=5):
n_strides = ((arr.size-windows_len)//stride_len)+1
return np.array([arr[s:(s+windows_len)] for s in np.arange(0, n_strides*stride_len,stride_len)])
gen_strides(np.arange(15), stride_len=2, windows_len=4)
Out[207]:
array([[ 0, 1, 2, 3],
[ 2, 3, 4, 5],
[ 4, 5, 6, 7],
[ 6, 7, 8, 9],
[ 8, 9, 10, 11],
[10, 11, 12, 13]])

移动平均值

cumsum :计算轴向元素累加和,返回由中间结果组成的数组

cumprod :计算轴向元素累乘积,返回由中间结果组成的数组

1
2
3
4
5
6
7
8
9
10
data = np.array([1] * 10)
acum = data.cumsum()
cump = acum.cumprod()

print(acum)
[ 1 2 3 4 5 6 7 8 9 10]

print(cump)
array([ 1, 2, 6, 24, 120, 720, 5040,
40320, 362880, 3628800])
1
2
3
4
5
6
7
8
9
10
11
# 37. 窗口大小为3的移动平均值
def moving_average(a, n=3):
ret = np.cumsum(a, dtype=float)
ret[n:] = ret[n:]-ret[:-n]
return ret[n-1:]/n
np.random.seed(100)
Z = np.random.randint(10, size=10)
Z
Out[191]: array([8, 8, 3, 7, 7, 0, 4, 2, 5, 2])
moving_average(Z, n=3).round(2)
Out[192]: array([6.33, 6. , 5.67, 4.67, 3.67, 2. , 3.67, 3. ])

第n个重复项的索引

1
2
3
4
5
6
7
8
# 36. 第n个重复项的索引
# 找出x中第1个重复n次的索引
arr = np.array([1,2,1,1,3,4,3,1,1,2,1,1,2])
n = 5
[ii for ii,kk in enumerate(arr) if kk==1][n-1]
Out[186]: 8
np.where(arr==1)[0][n-1]
Out[187]: 8

按列排序二维数组

1
2
3
4
5
6
7
8
9
10
11
12
# 31. 按列排序二维数组
arr = np.random.uniform(size=(3,4))
arr
Out[146]:
array([[0.54040458, 0.29679375, 0.1107879 , 0.3126403 ],
[0.45697913, 0.65894007, 0.25425752, 0.64110126],
[0.20012361, 0.65762481, 0.77828922, 0.7795984 ]])
arr[arr[:,1].argsort()]
Out[147]:
array([[0.54040458, 0.29679375, 0.1107879 , 0.3126403 ],
[0.20012361, 0.65762481, 0.77828922, 0.7795984 ],
[0.45697913, 0.65894007, 0.25425752, 0.64110126]])

pearsonr相关系数

1
2
3
4
5
6
7
8
9
10
11
# 25. 计算某两列的pearsonr相关系数
arr = np.random.uniform(size=(3,4))
arr
Out[114]:
array([[0.59884338, 0.60380454, 0.10514769, 0.38194344],
[0.03647606, 0.89041156, 0.98092086, 0.05994199],
[0.89054594, 0.5769015 , 0.74247969, 0.63018394]])
from scipy.stats.stats import pearsonr
corr,p_value = pearsonr(arr[:,0], arr[:,2])
corr
Out[117]: -0.432641494562719

唯一值的数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 27. 查找numpy数组中的唯一值的数量
arr = np.random.uniform(size=(3,4))
np.unique(arr, return_counts=True)
Out[121]:
(array([0.04486228, 0.14260031, 0.17808099, 0.23769421, 0.34019022,
0.35479561, 0.37625245, 0.50543143, 0.5928054 , 0.62994188,
0.9338413 , 0.94637988]),
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=int64))

# 28. 将数值转换为分类(文本)数组
# 将iris_2d的花瓣长度(第3列)组成一个文本数组
# <3 -> '小'
# 3-5 -> '中'
# >=5 -> '大
from sklearn import datasets
iris = datasets.load_iris().data
petal_length_bin = np.digitize(iris[:,2].astype('float'), [0,3,5,10])
label_map = {1:'small', 2:'medium', 3:'large', 4:np.nan}
petal_length_cat = [label_map[x] for x in petal_length_bin]
petal_length_cat[:4]
Out[130]: ['small', 'small', 'small', 'small']

多个条件过滤numpy数组

1
2
3
4
5
6
7
8
9
10
11
# 24. 根据两个或多个条件过滤一个numpy数组
# 过滤具有arr(第3列)> 0.5和arr(第1列)<0.8的arr的行。
arr = np.random.uniform(size=(3,4))
arr
Out[110]:
array([[0.81622475, 0.27407375, 0.43170418, 0.94002982],
[0.81764938, 0.33611195, 0.17541045, 0.37283205],
[0.00568851, 0.25242635, 0.79566251, 0.01525497]])
condition = (arr[:,2]>0.5) & (arr[:,0]<0.8)
arr[condition]
Out[112]: array([[0.00568851, 0.25242635, 0.79566251, 0.01525497]])

堆叠数组操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 2. 垂直堆叠两个数组
a = np.arange(10).reshape(2,-1)
b = np.repeat(1,10).reshape(2,-1)
a
Out[10]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
b
Out[11]:
array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
np.concatenate([a,b], axis=0)
Out[12]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
np.vstack([a,b])
Out[13]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
np.r_[a,b]
Out[14]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])

# 3. 水平堆叠两个数组
np.concatenate([a,b], axis=1)
Out[15]:
array([[0, 1, 2, 3, 4, 1, 1, 1, 1, 1],
[5, 6, 7, 8, 9, 1, 1, 1, 1, 1]])
np.hstack([a,b])
Out[16]:
array([[0, 1, 2, 3, 4, 1, 1, 1, 1, 1],
[5, 6, 7, 8, 9, 1, 1, 1, 1, 1]])
np.c_[a,b]
Out[17]:
array([[0, 1, 2, 3, 4, 1, 1, 1, 1, 1],
[5, 6, 7, 8, 9, 1, 1, 1, 1, 1]])

提取范围内的所有数字

1
2
3
4
5
6
7
8
# 8. 提取给定范围内的所有数字
a = np.arange(15)
index = np.where((a>=5) & (a<=10))
a[index]
Out[36]: array([ 5, 6, 7, 8, 9, 10])
index = np.where(np.logical_and(a>=5, a<=10))
a[index]
Out[38]: array([ 5, 6, 7, 8, 9, 10])

交换数组行列

1
2
3
4
5
6
7
8
9
10
11
12
13
# 10. 交换2维numpy数组中的两个列
np.arange(9).reshape(3,3)[:,[1,0,2]]
Out[46]:
array([[1, 0, 2],
[4, 3, 5],
[7, 6, 8]])

# 11. 交换2维numpy数组中的两个行
np.arange(9).reshape(3,3)[[1,0,2], :]
Out[47]:
array([[3, 4, 5],
[0, 1, 2],
[6, 7, 8]])

反转2维数组行列

1
2
3
4
5
6
7
8
9
10
11
12
13
# 12. 反转2维数组的行
np.arange(9).reshape(3,3)[[1,0,2], :]
Out[51]:
array([[3, 4, 5],
[0, 1, 2],
[6, 7, 8]])

# 13. 反转2维数组的列
np.arange(9).reshape(3,3)[:,::-1]
Out[48]:
array([[2, 1, 0],
[5, 4, 3],
[8, 7, 6]])

数组打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 15. 打印三位小数的numpy数组
np.set_printoptions(3)
np.random.uniform(5,10,(5,3))
Out[59]:
array([[5.427, 6.768, 6.71 ],
[7.243, 6.434, 7.314],
[6.692, 8.417, 7.965],
[8.718, 5.061, 5.936],
[5.918, 8.064, 7.431]])

# 16. 使用科学记数法(如1e10)漂亮的打印数组rand_arr
np.random.seed(100)
np.set_printoptions(suppress=True)
rand_arr = np.random.random([3,3])/1e3
rand_arr
Out[68]:
array([[0.000543, 0.000278, 0.000425],
[0.000845, 0.000005, 0.000122],
[0.000671, 0.000826, 0.000137]])

# 17. 限制数组输出中打印元素的数量
np.set_printoptions(threshold=6)
arr = np.arange(15)
arr
Out[73]: array([ 0, 1, 2, ..., 12, 13, 14])

标准化一个数组至0到1之间

1
2
3
4
5
6
7
8
9
10
11
12
13
# 20. 标准化一个数组至0到1之间
arr = np.random.uniform(size=(3,4))
arr
Out[89]:
array([[0.88959857, 0.64348368, 0.66692863, 0.41213651],
[0.78437761, 0.75333385, 0.10293507, 0.7942196 ],
[0.82432451, 0.11447181, 0.30328525, 0.41767367]])
s_max,s_min = arr.max(axis=0),arr.min(axis=0)
(arr-s_min)/(s_max-s_min)
Out[91]:
array([[1. , 0.82805338, 1. , 0. ],
[0. , 1. , 0. , 1. ],
[0.37964781, 0. , 0.35523487, 0.01449204]])

缺失值相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 26. 找出数组是否有缺失的值
arr = np.random.uniform(size=(3,4))
np.isnan(arr).any()
Out[119]: False

# 34. 删除所有nan值
arr = np.array([1,2,3,np.nan,5,6,7,np.nan])
arr[~np.isnan(arr)]
Out[167]: array([1., 2., 3., 5., 6., 7.])

# 23. 数据集的5个随机位插入np.nan值
arr = np.random.uniform(size=(3,4))
i,j = np.where(arr)
np.random.seed(100)
arr[np.random.choice((i),5), np.random.choice((j),5)] = np.nan
arr
Out[103]:
array([[ nan, 0.57138137, 0.27694632, 0.06905881],
[0.25886229, nan, nan, 0.0125819 ],
[ nan, 0.06872554, nan, 0.28179248]])
np.where(np.isnan(arr))
Out[105]: (array([0, 1, 1, 2, 2], dtype=int64), array([0, 1, 2, 0, 2], dtype=int64))

数组交差集

1
2
3
4
5
6
7
8
9
10
11
# 5. 数组之间的共同元素
a = np.array([1,2,3,2,3,4,3,4,5,6])
b = np.array([7,2,10,2,7,4,9,4,9,8])
np.intersect1d(a,b)
Out[27]: array([2, 4])

# 6. 删除存在于另一个数组中的元素
a = np.array([1,2,3,4,5])
b = np.array([5,6,7,8,9])
np.setdiff1d(a,b)
Out[30]: array([1, 2, 3, 4])

数组产生

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 4. 生成自定义序列
a = np.array([1,2,3])
np.r_[np.repeat(a,3), np.tile(a,3)].reshape(2,-1)
Out[24]:
array([[1, 1, 1, 2, 2, 2, 3, 3, 3],
[1, 2, 3, 1, 2, 3, 1, 2, 3]])

# 14. 二维数组,以包含5到10之间的随机浮点数
rand_arr = np.random.randint(low=5, high=10, size=(5,3)) + np.random.random((5, 3))
rand_arr
Out[56]:
array([[5.37441948, 8.61709329, 8.24544657],
[6.79517054, 6.43953972, 5.01129723],
[9.662239 , 6.24575781, 6.51341089],
[8.01997704, 6.66118956, 8.18283188],
[8.02228762, 6.9609364 , 7.4676691 ]])
rand_arr = np.random.uniform(5,10, size=(5,3))
rand_arr
Out[58]:
array([[7.13046251, 7.4977751 , 8.55210656],
[7.9222628 , 5.7828763 , 9.57743131],
[9.13648012, 5.71533963, 9.18622945],
[5.94241285, 8.08918632, 9.32716147],
[5.75027771, 8.83210586, 8.3991677 ]])

元素查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 19. 从一维元组数组中提取特定的列
iris_2d = np.array([row.tolist()[:4] for row in irirs_ld])
iris_2d[:4]
Out[78]:
array([[5.1, 3.5, 1.4, 0.2],
[4.9, 3. , 1.4, 0.2],
[4.7, 3.2, 1.3, 0.2],
[4.6, 3.1, 1.5, 0.2]])

# 22. 找到数组的百分位的值
# 第5位和第95百分位的值
arr = np.random.uniform(size=(3,4))
np.percentile(arr, q=[5,95])
Out[94]: array([0.31394255, 0.87443495])

# 30. 获得数组中第二大的元素值
arr = np.random.uniform(size=(3,4))
np.unique(np.sort(arr))[-2]
Out[132]: 0.9570126003527981

# 32. 首次出现的值大于给定值的位置
arr = np.random.uniform(size=(3,4))
arr
Out[150]:
array([[0.61032815, 0.30900035, 0.69773491, 0.8596183 ],
[0.62532376, 0.98240783, 0.97650013, 0.16669413],
[0.02317814, 0.16074455, 0.92349683, 0.95354985]])
np.argmax(arr[:,2].astype('float') > 0.7)
Out[151]: 1

# 35. 一维数组所有局部最大值(或峰值)
arr = np.array([1,3,7,1,2,6,0,1])
doublediff = np.diff(np.sign(np.diff(arr)))
peak_locations = np.where(doublediff==-2)[0]+1
peak_locations
Out[180]: array([2, 5], dtype=int64)