【Data Mining】机器学习三剑客之Numpy常用用法总结
作者:陈老师 个人公众号:接地气学堂
陈老师新课:商业分析全攻略 https://edu.hellobi.com/course/308 用数据分析方法解决商业问题,目前已经100+学员加入!5星好评。分析思维双剑合璧,四大板块:概念篇、行业篇、思维篇、套路篇
一、前言
玩数据分析、数据挖掘、AI的都知道这个python库用的是很多的,里面包含各种操作,在实际的dataset的处理当中是非常常用的,这里我做一个总结,方便自己看,也方便大家看,我准备做一个非常细致的分类,每个分类有对应的numpy常用用法,以后见到或者用到再一个个慢慢加进来,如果我还用csdn我就会移植update下去。
二、下载、安装、导入
用anaconda安装是十分方便的,如果你已经安装了tf,keras之类的,其实已经直接把numpy安装了,一般来说安装就是pip命令。
1pip install numpy#py2
2pip3 install numpy#py3
用法则是
1importnumpyasnp# 一般as为np来操作
三、常用用法总结
1.array基本信息以及生成各种常见array基本操作
生成array,得到对应的基本信息
1importnumpyasnp
2
3array = np.array([[1,2,3],
4[2,3,4]])
5
6printarray#numpy生成的array
7printarray.dtype# 每个元素的类型
8print"number of dim", array.ndim# array的维度
9print'shape:', array.shape#形状, 两行三列。
10print'size:', array.size#array的大小=array中所有元素的个数
11"""
12[[1 2 3]
13[2 3 4]]
14int64
15number of dim 2
16shape: (2, 3)
17size: 6
18"""
array的生成就是np.array(list),本质上是把定义的list转换成array,因为array可以进行更加方便地计算和操作,比如矩阵的转置和相乘。
array的dtype设置
1importnumpyasnp
2
3a = np.array([2,23,4], dtype=np.float32)
4print"a's dtype", a.dtype
5aa = np.array([2,23,4], dtype=np.int)
6print"aa's dtype", aa.dtype
7aaa = np.array([2,23,4])
8print"aaa's dtype", aaa.dtype
9aaaa = np.array([2.2,23.2,4.2])
10print"aaaa's dtype", aaaa.dtype
11aaaaa = np.array([2,23,4], dtype=np.int64)
12print"aaaaa's dtype:", aaaaa.dtype
13
14"""
15a's dtype float32
16aa's dtype int64
17aaa's dtype int64
18aaaa's dtype float64
19aaaaa's dtype: int64
20"""
由可以得到一个结论就是如果定义的array里面的list的元素本身为整数的话,不设置type,则默认为int64,如果设置为int类型而没有设置字节大小则还是默认为int64,如果元素本身为小数,则默认为float64。
所以如果用int64,则如果元素都为整数则不需要设置默认即可,设置其他类型需要设置,float类似。
生成常见array格式
1a1 = np.zeros((2,3), dtype=np.int)# 生成shape=(2, 3)的全为0的array
2
3printa1
4"""
5[[0 0 0]
6[0 0 0]]
7"""
8
9a2 = np.ones((3,4), dtype=np.int16)# 生成shape=(3, 4)的全为1的array
10
11printa2
12"""
13[[1 1 1 1]
14[1 1 1 1]
15[1 1 1 1]]
16"""
这里注意shape=(a,b),在填入shape的参数的时候一定要加括号,以下雷同。
1a3 = np.empty((3,4))# 生成shape=(3, 4)的全为接近空的array
2printa3
3"""
4[[6.92259773e-310 4.67497449e-310 6.92259751e-310 6.92259750e-310]
5[2.37151510e-322 3.16202013e-322 0.00000000e+000 6.92257087e-310]
6[6.92259748e-310 6.92257087e-310 6.92257063e-310 6.92257063e-310]]
7"""
8a4 = np.arange(10,20,2)# 生成array 10到20 每隔2的一增加,for循环中主要使用
9printa4
10"""
11[10 12 14 16 18]
12"""
13
14a5 = np.arange(12)# 生成array 0到12-1=11 每一个增加,for循环中非常常用
15printa5
16"""
17[ 0 1 2 3 4 5 6 7 8 9 10 11]
18"""
19
20a6 = np.arange(12).reshape((3,4))# 这里主要展示reshape的功能,能够重新定义矩阵的形状
21printa6
22"""
23[[ 0 1 2 3]
24[ 4 5 6 7]
25[ 8 9 10 11]]
26"""
27# 1和10之间4个元素越过,这个主要应用在插值运算或者matplotlib画光滑曲线的时候计算用到。
28a7 = np.linspace(1,10,4).reshape((2,2))
29
30printa7
31"""
32[[ 1. 4.]
33[ 7. 10.]]
34
35"""
2.array之间的计算
加减法
相同维度:
1importnumpyasnp
2
3a = np.array([10,20,30,40])
4b = np.arange(4)
5print"a:", a
6print"b:", b
7c = a+b
8print"c:", c
9c1 = a-b
10print"c1:", c1
11"""
12a: [10 20 30 40]
13b: [0 1 2 3]
14c: [10 21 32 43]
15c1: [10 19 28 37]
16"""
不同维度:
1aa = np.array([[1,2,3,4],
2[11,22,33,44]])
3
4bb = np.arange(4)
5
6print"aa:", aa
7print"bb:", bb
8print"a+b:", aa+bb
9
10"""
11aa: [[ 1 2 3 4]
12[11 22 33 44]]
13bb: [0 1 2 3]
14a+b: [[ 1 3 5 7]
15[11 23 35 47]]
16"""
如果是不同维度的array进行加减法的话,程序就是把维度低的array自动复制扩展到大维度的array,进行相加 当然前提条件是两个不同维度的array进行相加的时候,低维度的array的shape也要和高维度的array其中一个shape相同,例如上面代码所示,(2,4) (1,4) 都有个shape为4
乘除法
1d = np.array([[1,2],
2[3,4]])
3e = np.arange(1,8,2).reshape((2,2))
4print"d:", d
5print"e:", e
6
7print"d*e:", d*e#对应元素相乘
8print"d/e", d/e#对应元素相除,因为是int64类型所以类似于2/3=0
9"""
10d: [[1 2]
11[3 4]]
12e: [[1 3]
13[5 7]]
14d*e: [[ 1 6]
15[15 28]]
16d/e [[1 0]
17[0 0]]
18"""
不同纬度的乘除法和上面加减法解析情况一样,可对比来看。
平方,三角函数,比较元素大小
1a = np.array([10,20,30,40])
2b = np.arange(4)
3c2 = b**2# 平方
4print"c2:", c2
5
6c3 =10*np.sin(a)# sin函数
7print"c3:", c3
8"""
9c2: [0 1 4 9]
10c3: [-5.44021111 9.12945251 -9.88031624 7.4511316 ]
11"""
12print"b:", b
13print"b:", b <3# b中小于3的都为TRUE
14print"b:", b ==3# b中等于3的为TRUE
15"""
16b: [0 1 2 3]
17b: [ True True True False]
18b: [False False False True]
19
20"""
矩阵相乘
1d = np.array([[1,2],
2[3,4]])
3e = np.arange(1,8,2).reshape((2,2))
4print"d:", d
5print"e:", e
6printnp.dot(d, e)
7printd.dot(e)
8"""
9d: [[1 2]
10[3 4]]
11e: [[1 3]
12[5 7]]
13[[11 17] #例如11 为1*1+2*5=11
14[23 37]]
15[[11 17]
16[23 37]]
17
18"""
np.dot(d, e) 与d.dot(e)一样,都为d和e进行矩阵相乘
随机数和max,min,sum
1f = np.random.random((2,4))#随机产生shape为(2,4)的一个array,每个元素都为0-1之间随机生成
2printf
3print"=------="
4printnp.sum(f)
5printnp.min(f)
6printnp.max(f)
7"""
8[[0.11027523 0.84841991 0.59866992 0.92557867]
9[0.99917522 0.2771565 0.25578198 0.06671013]]
10=------=
114.081767552987877
120.06671012832269874
130.9991752153886827
14"""
15print"============="
16printnp.sum(f, axis=0)
17printnp.min(f, axis=1)
18printnp.max(f, axis=0)
19"""
20[1.10945044 1.12557641 0.8544519 0.9922888 ]
21[0.11027523 0.06671013]
22[0.99917522 0.84841991 0.59866992 0.92557867]
23"""
顾名思义,sum为总,min为最小,max为最大,如果不设置axis维度参数的话,则都为整个array的元素来说,但一般我们运用都只是算某个维度的sum,max,min,在二维数据中,axis=0代表行,第一个维度,axis=1,代表列为第二个维度,其实这么记并不是很好很有可能记错,我一般都是这么记得:axis=0为行,那意思就是每一行都要算呗?算完那不就是一列的每一行算个数被,axis=1类推,多维数据类推即可
矩阵转置和排序,以及元素比较大小重置元素方法
1c = np.arange(14,2,-1).reshape((3,4))
2
3printc
4print"sort:", np.sort(c)# 每一行进行重新大小排序当然也有axis参数配置,根据我的axis参数说明来操作
5
6printnp.transpose(c)#转置 同下面操作
7printc.T# 转置 同上面操作
8
9print"clip:",np.clip(c,5,9)#c矩阵中的元素小于5的等于5,大于9的等于9
10"""
11[[14 13 12 11]
12[10 9 8 7]
13[ 6 5 4 3]]
14sort: [[11 12 13 14]
15[ 7 8 9 10]
16[ 3 4 5 6]]
17[[14 10 6]
18[13 9 5]
19[12 8 4]
20[11 7 3]]
21[[14 10 6]
22[13 9 5]
23[12 8 4]
24[11 7 3]]
25clip: [[9 9 9 9]
26[9 9 8 7]
27[6 5 5 5]]
28"""
平均值、中值,累加,后减前
1a = np.arange(2,14).reshape((3,4))
2print"a:", a
3print"average:", np.average(a)#平均值
4print"median:", np.median(a)#中值
5
6print"cumsum:", np.cumsum(a)#每个元素变成当前元素+前面所有元素的和
7print"diff:", np.diff(a)#当前元素减去前面元素的差
8"""
9a: [[ 2 3 4 5]
10[ 6 7 8 9]
11[10 11 12 13]]
12average: 7.5
13median: 7.5
14cumsum: [ 2 5 9 14 20 27 35 44 54 65 77 90]
15diff: [[1 1 1]
16[1 1 1]
17[1 1 1]]
18"""
3.索引
最大值最小值索引,非零索引
1a = np.array([[2,6,0,4],
2[4,8,9,1],
3[10,2,3,11]])
4print"argmin:", np.argmin(a)
5print"axis0:", np.argmin(a, axis=0)
6print"axis1:", np.argmin(a, axis=1)
7print"argmax:", np.argmax(a)
8print"zero:", np.nonzero(a)
9
10"""
11argmin: 2
12axis0: [0 2 0 1]
13axis1: [2 3 1]
14argmax: 11
15zero: (array([0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]), array([0, 1, 3, 0, 1, 2, 3, 0, 1, 2, 3]))
16"""
argmin/argmax都是返回最小值/最大值的索引的函数。
这里的axis和上面的分析是完全一致的,例如argmin(a)就是最小的索引,虽小的毋庸置疑是0,所以总体来讲从第一行第一个元素到最后一行最后一个元素,总体来算索引,那就是第二个为0,所以返回2,如果axis=0说明一列中的每一行来比较,那第一列比较出来最小的为2,即索引为0,因为每一列的每一行来比较所以最后的维度为列数,在这里即为4,以此列推。
非零索引的意思为非零的数返回索引,如上例为返回两个array,前面array对应行索引,后面对应列索引,一前一后加一起的shape才对应一个非零索引
取值,取列或行
1importnumpyasnp
2
3a = np.arange(3,15).reshape((3,4))
4
5printa
6printa[1]#索引为1的行,同下
7printa[:][1]#索引为1的行,同上
8print"=========-------==========="
9printa[2][1]#和数组一样的表示
10printa[2,1]#同上,这才是比较标准的array的索引表示,前面是行后面是列的索引
11print"=========---------============"
12printa[:,1]#索引为1的列,生成为行向量
13printa[:,1:2]#索引为1的列,生成为列向量
14printa[:,1:3]
15
16printa[1,1:3]#为上面a[:, 1:3]的索引为1的行向量
17"""
18[[ 3 4 5 6]
19[ 7 8 9 10]
20[11 12 13 14]]
21[ 7 8 9 10]
22[ 7 8 9 10]
23=========-------===========
2412
2512
26=========---------============
27[ 4 8 12]
28[[ 4]
29[ 8]
30[12]]
31[[ 4 5]
32[ 8 9]
33[12 13]]
34[8 9]
35"""
着重讲一下 a[:, 1:2] a[:, 1:3] a[1, 1:3]
a[:, 1:2]::代表行所有也就是一列要的话,这一列的每一行都要,1:2对应的从索引为1的列来算移植相当于取到索引为(2-1)的列,2为取的最高索引大一个。所以总体来讲就是首先取每一行,之后在行里取索引1->1的列元素,所以为最终的结果列向量。
a[:, 1:3]:按照上面的分析则每一行都要,列要索引为1和(3-1)的元素,那就是索引为1和2的所有元素,也就是第二列和第三列的元素。
a[1, 1:3]:为a[:, 1:3]的索引为1的所有元素。
这里需要注意的是
a[:, 1] #索引为1的列,生成为行向量,
a[:, 1:2] #索引为1的列,生成为列向量
因为两种取值的思想不一样,最终造成的结果也不一样,一个是直接取,所以维度减少了一个,另一个是在原本维度上截取,最终还是原来的维度。
迭代元素和降维
1a = np.arange(3,15).reshape((3,4))# 数据都是下取上差一个取到。
2printa
3print"row"
4forrowina:#取每一行迭代
5printrow
6print"column"
7forcolumnina.T:#每一列迭代
8printcolumn
9print"====================="
10printa.flatten()# 所有元素变成一维
11b = np.array([[1,2,3]])
12printb
13printb.flatten()#降维
14
15foritemina.flat:#每个元素打印
16printitem
17
18"""
19[[ 3 4 5 6]
20[ 7 8 9 10]
21[11 12 13 14]]
22row
23[3 4 5 6]
24[ 7 8 9 10]
25[11 12 13 14]
26column
27[ 3 7 11]
28[ 4 8 12]
29[ 5 9 13]
30[ 6 10 14]
31=====================
32[ 3 4 5 6 7 8 9 10 11 12 13 14]
33[[1 2 3]]
34[1 2 3]
353
364
375
386
397
408
419
4210
4311
4412
4513
4614
47"""
行迭代,就是可以理解为最外层的维度进行迭代,列迭代就是利用转置来完成。
flatten()函数的意思为把array的内层的维度进行降一维,将内层的维度弄掉,则二维数据就成为一维数据了
4.合并与分开
两个合并、多个合并(行向量转换成列向量)
1# -*- coding: utf-8 -*-
2importnumpyasnp
3
4a = np.array([1,1,2])
5b = np.array([2,3,4])
6
7c = np.vstack((a, b))#vertical
8
9print"a:", a
10print"b:", b
11print"c:", c
12print"a,c shape:", a.shape, c.shape
13
14d = np.hstack((a, b))#horizontal
15print"d:", d
16printd.shape
17"""
18a: [1 1 2]
19b: [2 3 4]
20c: [[1 1 2]
21[2 3 4]]
22a,c shape: (3,) (2, 3)
23d: [1 1 2 2 3 4]
24(6,)
25"""
26printa.T# not transponse 行向量无法直接用转置来变成列向量
27# 行向量变成列向量
28printa[np.newaxis, :].shape
29printa[:, np.newaxis].shape
30printa[:, np.newaxis]#转换方法
31"""
32[1 1 2]
33(1, 3)
34(3, 1)
35[[1]
36[1]
37[2]]
38"""
39a = np.array([1,1,2])[:, np.newaxis]
40b = np.array([2,3,4])[:, np.newaxis]
41
42c = np.concatenate((a, b, b), axis=0)#多向量融合
43
44printc
45
46c = np.concatenate((a, b, b), axis=1)#多向量融合
47
48printc
49
50"""
51[[1]
52[1]
53[2]
54[2]
55[3]
56[4]
57[2]
58[3]
59[4]]
60[[1 2 2]
61[1 3 3]
62[2 4 4]]
63"""
分开
1# -*- coding: utf-8 -*-
2importnumpyasnp
3
4a = np.arange(12).reshape((3,4))
5
6printa
7print"平等分开"
8print"vertical:", np.split(a,2, axis=1)#
9
10print"horizontal:", np.split(a,3, axis=0)#
11"""
12[[ 0 1 2 3]
13[ 4 5 6 7]
14[ 8 9 10 11]]
15平等分开
16vertical: [array([[0, 1],
17[4, 5],
18[8, 9]]), array([[ 2, 3],
19[ 6, 7],
20[10, 11]])]
21horizontal: [array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
22"""
23print"不平等分开"
24printnp.array_split(a,3, axis=1)
25
26print"代替需要axis参数"
27print"vertical_a:", np.vsplit(a,3)
28
29print"horizontal_a:", np.hsplit(a,2)
30"""
31不平等分开
32[array([[0, 1],
33[4, 5],
34[8, 9]]), array([[ 2],
35[ 6],
36[10]]), array([[ 3],
37[ 7],
38[11]])]
39代替需要axis参数
40vertical_a: [array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
41horizontal_a: [array([[0, 1],
42[4, 5],
43[8, 9]]), array([[ 2, 3],
44[ 6, 7],
45[10, 11]])]
46"""
5.元素传递和copy
1b = np.arange(4)
2
3printb
4c = b
5e = c
6d = e
7b[0] =11
8printb
9
10printcisb
11printdisb
12printb[0]
13
14d[1:3] = [22,22]
15printb
16printc
17
18c = b.copy()
19
20b[3] =44
21
22printb
23printc
24printe
25"""
26[0 1 2 3]
27[11 1 2 3]
28True
29True
3011
31[11 22 22 3]
32[11 22 22 3]
33[11 22 22 44]
34[11 22 22 3]
35[11 22 22 44]
36"""
array这个元素传递有点意思的,就是如果直接a=b,其实从内存角度来考虑就相当于a和b指向了一样的元素内存空间,所以改变一个元素的值,另一个一样改变,如果想各是各的,并且还想传递另一个元素的值那就用a=b.copy(),所以这个还是需要注意的
6.补充部分
array.min/max/ptp
1importnumpyasnp
2
3a = [[2,4,8,9], [1,7,4,5], [5,7,1,4]]
4a = np.array(a)
5print(a)
6print(a.min(0))
7print(a.min(1))
8print(a.ptp(0))
9"""
10[[2 4 8 9]
11[1 7 4 5]
12[5 7 1 4]]
13axis=0 为每列的最小值返回
14[1 4 1 4]
15axis=1 为每行的最小值返回
16[2 1 1]
17ptp为最大值减最小值的range
18[4 3 7 5]
19"""
np.random.choice
1importnumpyasnp
2
3a = np.random.choice(a=100, size=20)
4print(a)
5"""
60-99之间选size为20的随机数的list
7[78 82 91 96 5 60 28 79 24 56 5 34 58 48 96 57 77 23 80 69]
8"""