天天看点

python数据分析 -- numpy库初识

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

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

1. 导入Numpy库

要调用numpy库,我们就要导入这个库,导入的语句就一句。

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

2. 使用Aarry创建数组

2.1 通过Array传递List

标准Python的列表(list)中,元素本质是对象。

如:L = [1, 2, 3],需要3个指针和三个整数对象,对于数值运算比较浪费内存和CPU。

因此,Numpy提供了ndarray(N-dimensional array object)对象:存储单一数据类型的多维数组。

创建一维数组:

L = [, , , , , ]
print L
a = 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.shape
print b.shape
           

打印结果:

a是6行1列,b是3行4列

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

强制修改数组大小

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

b.shape = 4, 3
print 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, -1
print 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.dtype
print 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 d
print 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(, , )
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(, , , 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(, , , 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(, , , endpoint=True, base=)
print f
           

打印结果:

[           
            
         ]
           

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

[0 1 2 3 4 5 6 7 8 9]
           

获取某个元素

print a[]
           

获取索引为3的元素

3
           

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

print a[:]
           
[3 4 5]
           

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

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

下标为负表示从后向前数

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

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

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

步长为-1,即翻转

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

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

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

4.2 整数数组的存取

根据整数数组存取:当使用整数序列对数组元素进行存取时,

将使用整数序列中的每个元素作为下标,整数序列可以是列表(list)或者数组(ndarray)。

使用整数序列作为下标获得的数组不和原始数组共享数据空间。

//创建两个数组
a = np.logspace(, , , base=)
print a
i = np.arange(, , )
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[] = 
print b
print 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()
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 > 
           
[ True  True False  True False False False  True False  True]
           

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

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

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

a[a > ] = 
print 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的数组。

[ 0 10 20 30 40 50]
           

将行向量,转化成列向量

[[ 0]
 [10]
 [20]
 [30]
 [40]
 [50]]
           

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

[0 1 2 3 4 5]
           

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

f = b + c
print 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(, , ).reshape((-, )) + np.arange()
           

二维数组的切片

//大括号里,前面的list表示行的索引,后面的list表示列的索引
//比如第一个数提取的是行索引为0列索引为2
print a[(,,,), (,,,)]

//获取行号从3开始(包括3),列号是0,2,5的元素
print a[:, [, , ]]

//创建布尔类型的数组
i = np.array([True, False, True, False, False, True])
//获取为true的行
print a[i]
//获取为true的行的列索引为3的元素
print a[i, ]
           

打印结果:

[ 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 =   //均值
sigma =   //标准差

//创建一个50个元素的数组,收尾与均值相差三个标准差
x = np.linspace(mu -  * sigma, mu +  * sigma, ) 

//根据正太分布的公式写出y
y = np.exp(-(x - mu) **  / ( * sigma ** )) / (math.sqrt( * 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=, markersize=)

//有灰色格子
plot.grid(True)

//画出来吧,少年!
plot.show()
           

图形如下:

python数据分析 -- numpy库初识

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

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

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

图形画出来如下:

python数据分析 -- numpy库初识

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()
           
python数据分析 -- numpy库初识

5.4 胸型线

(前方高能。。。)

x = np.arange(, , -)
y = (- * x * np.log(x) + np.exp(-( * (x -  / np.e)) ** ) / ) / 
//设置画布大小
plot.figure(figsize=(,))
plot.plot(y, x, 'r-', linewidth=)
plot.grid(True)
plot.show()
           

这个图太辣眼睛了。。。男生心里估计已经浮现过ABCDEF了。。

python数据分析 -- numpy库初识

5.5 心形线

t = np.linspace(, , )
x =  * np.sin(t) ** 
y =  * np.cos(t) -  * np.cos(*t) -  * np.cos(*t) - np.cos(*t)
plot.plot(x, y, 'r-', linewidth=)
plot.grid(True)
plot.show()
           

嗯,这个图美,愿大家有情人终成眷属

python数据分析 -- numpy库初识

5.6 渐开线

t = np.linspace(, , num=)
x = t*np.sin(t) + np.cos(t)
y = np.sin(t) - t*np.cos(t)
plot.plot(x, y, 'r-', linewidth=)
plot.grid()
plot.show()
           
python数据分析 -- numpy库初识

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

继续阅读