python数据分析 -- numpy库初识

来源:互联网 发布:python中关键字参数 编辑:程序博客网 时间:2024/05/20 02:27

标签(空格分隔): 王小草机器学习笔记


python的强大之处不但因为简洁易学高效,还在于她有许多库,可以方便我们得到想要的计算。比如今天讲的numpy库,为python提供了快速的多维数组的处理能力。有人数,numpy库的出现使得python可以像matlab一样去计算了。(matlab是10年前乃至今日仍然大受青睐的草稿本式的编程语言)。

1. 导入Numpy库

要调用numpy库,我们就要导入这个库,导入的语句就一句。
as 后面是重命名,也可以说是缩写,在我们的程序中,我们只要写np,自动就代码numpy。这是约定俗称的一个简称,当其他人阅读你的代码的时候,他们也知道np代表的就是Numpy,所以缩写最好不要自己创新。

import numpy as np

2. 使用Aarry创建数组

2.1 通过Array传递List

标准Python的列表(list)中,元素本质是对象。
如:L = [1, 2, 3],需要3个指针和三个整数对象,对于数值运算比较浪费内存和CPU。
因此,Numpy提供了ndarray(N-dimensional array object)对象:存储单一数据类型的多维数组。

创建一维数组:

L = [1, 2, 3, 4, 5, 6]print La = np.array(L)print a

打印结果:

[1, 2, 3, 4, 5, 6][1 2 3 4 5 6]

创建多维数组:

嵌套多个list

b = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])print b

打印结果:

[[ 1  2  3  4] [ 5  6  7  8] [ 9 10 11 12]]

2.2 数组大小

查看数组大小

print a.shapeprint b.shape

打印结果:
a是6行1列,b是3行4列

(6L,)(3L, 4L)

强制修改数组大小

1.将3*4的数组改成4*3的数组

b.shape = 4, 3print b

打印结果:
从(3,4)改为(4,3)并不是对数组进行转置,而只是改变每个轴的大小,数组元素在内存中的位置并没有改变,还是按照1,2,3,4,5…12这样的顺序来排列的。

[[ 1  2  3] [ 4  5  6] [ 7  8  9] [10 11 12]]

2.当某个轴为-1时,将根据数组元素的个数自动计算此轴的长度

b.shape = 2, -1print b

打印结果:
行是2行,列为-1的话就表示根据行来定,所以是6列

[[ 1  2  3  4  5  6] [ 7  8  9 10 11 12]]

修改数组大小后成新数组

使用reshape方法,可以创建改变了尺寸的新数组,原数组的shape保持不变

c = b.reshape((4, -1))print c

创建的新数组,仍然与老数组共享内存,修改任意一个将影响另外一个。
比如修改b数组的第1行第2列的元素为20,再来看b和c两个数组的变化

2.3 获取数组的元素类型

查看数据类型

print a.dtypeprint b.dtype

创建指定元素类型的数组

可以通过dtype参数在创建时指定元素类型

d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.float)f = np.array([[1+4j, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.complex)print dprint f

打印结果:分别是浮点型与复数型

[[  1.   2.   3.   4.] [  5.   6.   7.   8.] [  9.  10.  11.  12.]][[  1.+4.j   2.+0.j   3.+0.j   4.+0.j] [  5.+0.j   6.+0.j   7.+0.j   8.+0.j] [  9.+0.j  10.+0.j  11.+0.j  12.+0.j]]

更改元素类型

如果更改元素类型,可以使用astype安全的转换

f = d.astype(np.int)print f

打印结果:

[[ 1  2  3  4] [ 5  6  7  8] [ 9 10 11 12]]

3. 使用函数创建

3.1 arrage

如果生成一定规则的数据,可以使用NumPy提供的专门函数
arange函数类似于python的range函数:指定起始值、终止值和步长来创建数组
和Python的range类似,arange同样不包括终值;但arange可以生成浮点类型,而range只能是整数类型

生成1开始,10结束(不包含10),步长为0.5的一个数组

a = np.arange(1, 10, 0.5)print a

打印结果:

[ 1.   1.5  2.   2.5  3.   3.5  4.   4.5  5.   5.5  6.   6.5  7.   7.5  8.  8.5  9.   9.5]

3.2 linespace

linspace函数通过指定起始值、终止值和元素个数来创建数组,缺省包括终止值

b = np.linspace(1, 10, 10)print b

打印结果:生成了一个1到10,步长为1的等差数列,并且时前闭后闭的。

[  1.   2.   3.   4.   5.   6.   7.   8.   9.  10.]

可以通过endpoint关键字指定是否包括终值 ,默认是包括的。

c = np.linspace(1, 10, 10, endpoint=False)print c

打印结果:生成了1到9的10个等差数列

[ 1.   1.9  2.8  3.7  4.6  5.5  6.4  7.3  8.2  9.1]

3.3 logspace

和linspace类似,logspace可以创建等比数列
下面函数创建起始值为10^1,终止值为10^2,有20个数的等比数列

d = np.logspace(1, 2, 20, endpoint=False)print d

打印结果:

[ 10.          11.22018454  12.58925412  14.12537545  15.84893192  17.7827941   19.95262315  22.38721139  25.11886432  28.18382931  31.6227766   35.48133892  39.81071706  44.66835922  50.11872336  56.23413252  63.09573445  70.79457844  79.43282347  89.12509381]

下面创建起始值为2^0,终止值为2^10(不包括),有10个数的等比数列

f = np.logspace(0, 10, 11, endpoint=True, base=2)print f

打印结果:

[  1.00000000e+00   2.00000000e+00   4.00000000e+00   8.00000000e+00   1.60000000e+01   3.20000000e+01   6.40000000e+01   1.28000000e+02   2.56000000e+02   5.12000000e+02   1.02400000e+03]

3.4 frombuffer, fromstring, fromfile

使用 frombuffer, fromstring, fromfile等函数可以从字节序列创建数组

s = 'ABCDZ'g = np.fromstring(s, dtype=np.int8)

打印结果:

[65 66 67 68 90]

4. 存取

4.1 常规办法

数组元素的存取方法和Python的标准方法相同
首先我们使用arange创建一个数组a

a = np.arange(10)
[0 1 2 3 4 5 6 7 8 9]

获取某个元素

print a[3]

获取索引为3的元素

3

获取一组元素,切片[3,6),左闭右开

print a[3:6]
[3 4 5]

省略开始下标,表示从0开始

print a[:5]
[0 1 2 3 4]

下标为负表示从后向前数

print a[3:]
[3 4 5 6 7 8 9]

取索引[1,8)步长为2

print a[1:8:2]
[1 3 5 7]

步长为-1,即翻转

print a[::-1]
[9 8 7 6 5 4 3 2 1 0]

切片数据是原数组的一个视图,与原数组共享内容空间,可以直接修改元素

a[1:4] = 10, 20, 30print a
[ 0 10 20 30  4  5  6  7  8  9]

4.2 整数数组的存取

根据整数数组存取:当使用整数序列对数组元素进行存取时,
将使用整数序列中的每个元素作为下标,整数序列可以是列表(list)或者数组(ndarray)。
使用整数序列作为下标获得的数组不和原始数组共享数据空间。

//创建两个数组a = np.logspace(0, 9, 10, base=2)print ai = np.arange(0, 10, 2)print i//利用i取a中的元素b = a[i]print b

打印结果

[   1.    2.    4.    8.   16.   32.   64.  128.  256.  512.][0 2 4 6 8][   1.    4.   16.   64.  256.]
//b的元素更改,a中元素不受影响b[2] = 1.6print bprint a

打印结果:b变了,a不变

[   1.     4.     1.6   64.   256. ][   1.    2.    4.    8.   16.   32.   64.  128.  256.  512.]

4.3 布尔数组的存取

使用布尔数组i作为下标存取数组a中的元素:返回数组a中所有在数组b中对应下标为True的元素
首先生成10个满足[0,1)中均匀分布的随机数

a = np.random.rand(10)print a
[ 0.84334711  0.54587789  0.41350371  0.73992619  0.00475762  0.0972838  0.0522206   0.6696739   0.33550459  0.64959176]

大于0.5的元素索引

print a > 0.5
[ True  True False  True False False False  True False  True]

大于0.5的元素,打印出了一组布尔类型的值,符合条件的为true

b = a[a > 0.5]print b
[ 0.84334711  0.54587789  0.73992619  0.6696739   0.64959176]

将原数组中大于0.5的元素截取成0.5

a[a > 0.5] = 0.5print a//b不受影响print b
[ 0.5         0.5         0.41350371  0.5         0.00475762  0.0972838  0.0522206   0.5         0.33550459  0.5       ][ 0.84334711  0.54587789  0.73992619  0.6696739   0.64959176]

4.4 二维数组的切片

生成二维数组

若我们想生成以下这样一个多维数组:
[[ 0 1 2 3 4 5]
[10 11 12 13 14 15]
[20 21 22 23 24 25]
[30 31 32 33 34 35]
[40 41 42 43 44 45]
[50 51 52 53 54 55]]

可以经过以下几步
先生成行向量,0到60,步长为10的数组。

a = np.arange(0, 60, 10)
  [ 0 10 20 30 40 50]

将行向量,转化成列向量

b = a.reshape(-1, 1)
[[ 0] [10] [20] [30] [40] [50]]

生成一个0到5,步长为1的行向量

c = np.arange(6)
[0 1 2 3 4 5]

将列向量b每一列都c行向量

f = b + cprint f
[[ 0  1  2  3  4  5] [10 11 12 13 14 15] [20 21 22 23 24 25] [30 31 32 33 34 35] [40 41 42 43 44 45]

将上面所有步骤合起来可以用一句代码表示:

a = np.arange(0, 60, 10).reshape((-1, 1)) + np.arange(6)

二维数组的切片

//大括号里,前面的list表示行的索引,后面的list表示列的索引//比如第一个数提取的是行索引为0列索引为2print a[(0,1,2,3), (2,3,4,5)]//获取行号从3开始(包括3),列号是0,2,5的元素print a[3:, [0, 2, 5]]//创建布尔类型的数组i = np.array([True, False, True, False, False, True])//获取为true的行print a[i]//获取为true的行的列索引为3的元素print a[i, 3]

打印结果:

[ 2 13 24 35][[30 32 35] [40 42 45] [50 52 55]][[ 0  1  2  3  4  5] [20 21 22 23 24 25] [50 51 52 53 54 55]][ 3 23 53]

5. 绘图

5.1 绘制正态分布概率密度函数

mu = 2  //均值sigma = 32  //标准差//创建一个50个元素的数组,收尾与均值相差三个标准差x = np.linspace(mu - 3 * sigma, mu + 3 * sigma, 50) //根据正太分布的公式写出yy = np.exp(-(x - mu) ** 2 / (2 * sigma ** 2)) / (math.sqrt(2 * math.pi) * sigma)//以x,y为横纵坐标,'r-'表示红色线,'ro-表示红色线加原点',linewidth为线的粗细度#plot.plot(x, y, 'ro-', linewidth=2)//或者也可以:用'go'表示绿色原点,markersize为原点大小plot.plot(x, y, 'r-', x, y, 'go', linewidth=2, markersize=8)//有灰色格子plot.grid(True)//画出来吧,少年!plot.show()

图形如下:
QQ截图20160905162243.png-25.9kB

接下去,我们再来看几个好玩的画图案例

5.2 损失函数:Logistic损失(-1,1)/SVM Hinge损失/ 0/1损失

x = np.linspace(-3, 3, 1000)y_logit = np.log(1 + np.exp(-x)) / math.log(2)y_01 = x < 0y_hinge = 1 - xy_hinge[y_hinge < 0] = 0//label表示标记plot.plot(x, y_logit, 'r-', label='Logistic Loss', linewidth=2)plot.plot(x, y_01, 'g-', label='0/1 Loss', linewidth=2)plot.plot(x, y_hinge, 'b-', label='Hinge Loss', linewidth=2)plot.grid()//标记的放的位置,这里是右上角plot.legend(loc='upper right')plot.show()

图形画出来如下:
QQ截图20160905162424.png-29.9kB

5.3 x^x

x = np.linspace(-1.3, 1.3, 101)y = f(x)plot.plot(x, y, 'g-', label='x^x', linewidth=2)plot.grid()plot.legend(loc='upper right')plot.show()

QQ截图20160905162629.png-26.1kB

5.4 胸型线

(前方高能。。。)

x = np.arange(1, 0, -0.001)y = (-3 * x * np.log(x) + np.exp(-(40 * (x - 1 / np.e)) ** 4) / 25) / 2//设置画布大小plot.figure(figsize=(5,7))plot.plot(y, x, 'r-', linewidth=2)plot.grid(True)plot.show()

这个图太辣眼睛了。。。男生心里估计已经浮现过ABCDEF了。。
QQ截图20160905162940.png-19.3kB

5.5 心形线

t = np.linspace(0, 7, 100)x = 16 * np.sin(t) ** 3y = 13 * np.cos(t) - 5 * np.cos(2*t) - 2 * np.cos(3*t) - np.cos(4*t)plot.plot(x, y, 'r-', linewidth=2)plot.grid(True)plot.show()

嗯,这个图美,愿大家有情人终成眷属
QQ截图20160905163213.png-23.7kB

5.6 渐开线

t = np.linspace(0, 50, num=1000)x = t*np.sin(t) + np.cos(t)y = np.sin(t) - t*np.cos(t)plot.plot(x, y, 'r-', linewidth=2)plot.grid()plot.show()

QQ截图20160905163233.png-49.4kB

关于画函数图,总结规律,其实就是,设置一个x的变量,然后根据某种公式用x得到y的分布,然后把x,y用Plot函数套进去,什么颜色啊,圆点啊,线条粗细啊之类的都可以套模板写。棒棒棒!

0 0
原创粉丝点击