python数据分析之Numpy

Numpy是python的一种开源的数值计算扩展。这种工具可以用来储存和处理大型矩阵,比python自身的嵌套列表结构要高效的多。Numpy提供了许多高级的数值编程工具。Numpy的一个重要特性是他的数据组计算,是我们做的数据必不可少的一个包。

导入python库使用关键字import,后面可以自定义库的简称,但是一般都将Numpy命名为np,pandas命名为pd。

使用前一定要先导入Numpy包,导入的方法有以下几种:

1.import numpy

2.import numpy as np

3.form numpy import

Numpy的数组对象及其索引

数组上的数学操作

假如我们想将列表中的每个元素增加1,但列表不支持这样的操作:

a=[1,2,3,4]
a+1
print(a+1)      #列表不支持这样的操作,报错
a=[1,2,3,4]
[x+1 for x in a]
print([x+1 for x in a])    #列表只能这样,才能将每个元素增加1

将两个列表元素对应相加

a=[1,2,3,4]                
b=[2,3,4,5]
print(a+b)               #这是两个列表拼接
​
#结果:
[1, 2, 3, 4, 2, 3, 4, 5]
a=[1,2,3,4]
b=[2,3,4,5]
print([x+y for (x,y) in zip(a,b)])   #两个列表元素对应相加


#结果:
[3, 5, 7, 9]
这样的操作比较麻烦,而且在数据量特别大的时候会非常耗时间。如果我们使用Numpy,就会变得简单。

例:建一个数组,在每个元素上加1

import numpy as np
a=np.array([1,2,3,4])
print(a)
​
#结果:
[1 2 3 4]
​
b=a+1
print(b)
​
#结果:
[2 3 4 5]

例:两个数组元素对应相加

import numpy as np
a=np.array([1,2,3,4])
b=np.array([2,3,4,5])
print(a+b)
​
#结果:
[3 5 7 9]

产生数据的方式:

从列表产生数组:

import numpy as np
list=[0,1,2,3]
a=np.array(list)
print(a)

从列表传入:

import numpy as np
a=np.array([1,2,3,4])
print(a)

生成0数组:

import numpy as np
a=np.zeros(5)
print(a)

生成全1的数组:

import numpy as np
a=np.ones(5,dtype='int')
print(a)

可以使用fill方式将数组设定为指定值:

fill会自动进行取整,如果想变成小数,强制进行转换。

import numpy as np
a=np.array([1,2,3,4])
a.fill(5)
print(a)
a=a.astype('float')     #进行转换

与列表不同,数组中要求所有元素的dtype是一样的,如果传入参数的类型与数组类型不一样,需要按照已有的类型进行转换。还可以使用一些特定的方法生成特殊的数组

生成整数序列:

import numpy as np
a=np.arange(1,10,2)      #这个里面括号是左闭右开,2是步长
print(a)

#结果
[1 3 5 7 9]

生成等差序列:

import numpy as np
a=np.linspace(1,10,10)   #这里括号是双闭的,第二个10是有10个元素
print(a)

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

生成随机数:

import numpy as np
a=np.random.rand(10)    #0-1随机生成10个元素
print(a)

#结果:
[0.49364252 0.91044541 0.40119152 0.33678082 0.85807913 0.62023705 0.51507097 0.52876382 0.88644618 0.99546188]

import numpy as np
a=np.random.randn(10)   #随机生成10个正太分布
print(a)

#结果:
[ 0.46166455  0.78830024  0.55848265  1.0556776   0.92748966 -0.07222513 -1.91709458  0.76603085  0.63207431  0.03019785]

import numpy as np
a=np.random.randint(1,10,10)  #随机生成10个整数
print(a)

#结果:
[5 6 2 2 5 3 1 7 5 9]

数组属性

查看类型:

print(type(a))    #查看类型

查看数组中的数据类型:

print(a.dtype)     #查看数组的数据类型

查看形状,会返回一个元组,每个元素代表这一维的元素数目:

print(a.shape)    

查看数组里面元素数目:

print(a.size)

查看数组维度:

print(a.ndim)

索引与切片

和列表相似,数组也支持索引和切片操作。

索引第一个元素:

import numpy as np
a=np.array([0,1,2,3])
print(a[0])

#结果:
0

修改第一个元素的值:

import numpy as np
a=np.array([0,1,2,3])
a[0]=10
print(a)

#结果:
[10  1  2  3]

切片,支持负索引:

import numpy as np
a=np.array([11,12,13,14,15])
print(a[1:3])
print(a[1:-2])
print(a[-4:3])

#结果:
[12 13]
[12 13]
[12 13]

省略参数:

import numpy as np
a=np.array([11,12,13,14,15])
print(a[-2:])
print(a[::2])

#结果:
[14 15]
[11 13 15]

例:假设我们记录一部电影的累计票房:

import numpy as np
ob=np.array([21000,21800,22240,23450,25000])
print(ob) 
#结果:
[21000 21800 22240 23450 25000]

可以计算每天的票房:

ob2=ob[1:]-ob[:-1]
print(ob2)
#结果:
[ 800  440 1210 1550]

多维数组及其属性

array还可以用来生成多维数组:

import numpy as np
a=np.array([[0,1,2,3],[10,11,12,13]])
print(a)
#结果:
[[ 0  1  2  3]
 [10 11 12 13]]

事实上我们传入的是一个一列表为元素的列表,最终得到一个二维数组。

查看形状:

print(a.shape)
#结果:
(2, 4)

查看总的元素个数:

print(a.size)
#结果:
(2, 4)

查看维数:

print(a.ndim)
#结果:
2

多维数组索引

对于二维数组,可以传入两个数字来索引:

import numpy as np
a=np.array([[0,1,2,3],[10,11,12,13]])
print(a[1,3])
#结果:
13

其中,1是行索引,3是列索引,中间用逗号隔开,事实上,python会将他们看成一个元组(1,3),然后按照顺序进行对应。

可以利用索引给他赋值:

a[1,3]=-1
print(a)
#结果:
[[ 0  1  2  3]
 [10 11 12 -1]]

事实上,我们还可以使用单个索引来索引一整行内容:

print(a[1])
#结果:
[10 11 12 -1]

print(a[:,1])   #按列输出,行索引在逗号前面,列索引在逗号后面
#结果:
[ 1 11]

python会将这单个元组当成对第一维的索引,然后返回对应的内容。

多维数组切片

多维数组,也支持切片操作

想得到第一行的第4和第5两个元素:

import numpy as np
a=np.array([[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]])
print(a)
print(a[0,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]]
[4 5]

得到最后两行的最后两列:

print(a[4:,4:])
#结果:
[[44 45]
 [54 55]]

得到第三列:

print(a[:,2])
#结果:
[ 2 12 22 32 42 52]

每一维都支持切片的规则,包括负索引,省略:

[lower:upper:step]

例如,取出3,5行的奇数列:

print(a[2::2,::2])
#结果:
[[20 22 24]
 [40 42 44]]

切片是引用

切片在内存中使用的是引用机制。

import numpy as np
a=np.array([0,1,2,3,4])
b=a[2:4]
print(b)
#结果:
[2 3]


b[0]=10
print(a)              #[2 3]中将10赋值给b[0]
#结果:
[ 0  1 10  3  4]

引用机制意味着,python并没有为b分配新的空间来存储它的值,而是让b指向a所分配的内存空间,因此,改变b会改变a的值:

而这种现象在列表中并不会出现:

a=[1,2,3,4,5]
b=a[2:4]
b[0]=10          #列表中并没有将10赋值给b[0]
print(a)
#结果:
[1, 2, 3, 4, 5]

这样的好处在于对于很大的数组,不用大量复制多余的值,节约了空间。

缺点在于可能出现改变一个值改变另一个值得情况。

一个解决方法是使用copy()方法产生一个复制,这个复制会申请新的内存:

import numpy as np
a=np.array([0,1,2,3,4])
b=a[2:4].copy             #在新申请的内存中将a[2:4]赋值给b
print(a)  				#这里输出的是原来的内存
#结果:
[0 1 2 3 4]

花式索引

切片只支持连续或者等间隔的切片操作,要实现任意位置的操作,需要使用花式索引fancy slicing。

一维花式索引

与range函数类似,我们可以使用arange函数来产生等差数组。

import numpy as np
a=np.arange(0,100,10)
print(a)

花式索引需要指定索引位置:

index=[1,2,-3]
y=a[index]
print(y)
#结果:
[10 20 70]

还可以使用布尔数组来花式索引:

mask=np.array([0,2,2,0,0,1,0,0,1,0],dtype=bool)
print([mask])
#结果:
[array([False,  True,  True, False, False,  True, False, False,  True,
       False])]

mask必须是布尔数组。长度必须和数组长度相等。

print(a[mask])
#结果:
[10 20 50 80]

二维花式索引

对于花式索引,我们需要给定行和列的值:

import numpy as np
a=np.array([[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]])
print(a)

#结果:
[[ 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]]

返回的是一条次对角线上的5个值。

b=a[(0,1,2,3,4),(1,2,3,4,5)]
print(b)
#结果:
[ 1 12 23 34 45]

返回的是最后三行的第1,3,5列。

b=a[3:,[0,2,4]]
print(b)
#结果:
[[30 32 34]
 [40 42 44]
 [50 52 54]]

也可以使用mask进行索引:

mask=np.array([1,0,1,0,0,1],dtype=bool)
print(a[mask,2])
#结果:
[ 2 22 52]         #第三列中[2,12,22,32,42,52],对应[1,0,1,0,0,1]。可输出[2 32 52]

与切片不同,花式索引返回的是原对象的一个复制而不是引用。

“不完全”索引

只给定行索引的时候,返回整行:

y=a[:3]
print(y)
#结果:
[[ 0  1  2  3  4  5]
 [10 11 12 13 14 15]
 [20 21 22 23 24 25]]

这个时候也可以使用花式索引取出第2,3,5行:

con=np.array([0,1,1,0,1,0],dtype=bool)
b=a[con]
print(b)
#结果:
[[10 11 12 13 14 15]
 [20 21 22 23 24 25]
 [40 41 42 43 44 45]]

where语句

where(array)

where 函数会返回所有非零元素的索引。

一维数组

先看一维的例子:

import numpy as np
a=np.array([0,12,5,20])

判断数组中的元素是不是大于10:

print(a>10)
#结果:
[False  True False  True]

数组中所有大于10的元素的索引位置:

b=np.where(a>10)
print(b)
#结果:
(array([1, 3], dtype=int64),)

注意到where的返回值是一个元组。返回的是索引位置,索引[1,3]大于10的数

也可以直接用数组操作。

print(a[a>10])
#结果:
[12 20]

b=a[np.where(a>10)]
print(b)
#结果:
[12 20]

2.数组类型

 

类型转换

import numpy as np
a=np.array([1.5,-3],dtype=float)
print(a)
#结果:
[ 1.5 -3. ]

asarray函数

import numpy as np
a=np.array([1,2,3])
print(np.asarray(a,dtype=float))
#结果:
[1. 2. 3.]

astype方法

import numpy as np
a=np.array([1,2,3])
b=a.astype(float)
print(b)

#结果:
[1. 2. 3.]

b[0]=0.5
print(b)
#结果:
[0.5 2.  3. ]

print(a)
#结果:
[1 2 3]

3.数组操作

以豆瓣10部最高电影为例:

 

数组排序

sort函数

 argsort函数

argsort返回从小到大的排序在数组中的索引位置:

 求和

 

最大值

 

最小值

 均值

 标准差

 相关系数矩阵

 

多维数组操作

数组形状

import numpy as np 

a=np.arange(6) 

a.shape=2,3         #2行3列 print(a) 

#结果:

[[0 1 2] [3 4 5]]

与之对应的方法是reshape,但它不会修改原来数组的值,而是返回一个新的数组:

print(a.reshape(2,3))
print(a)
#结果:
[[0 1 2]
 [3 4 5]]
[0 1 2 3 4 5]

转置

a.shape=2,3
print(a)
#结果:
[[0 1 2]
 [3 4 5]]

print(a.T)
#结果:
[[0 3]
 [1 4]
 [2 5]]

print(a.transpose())
#结果:
[[0 3]
 [1 4]
 [2 5]]

数组连接

有时我们需要将不同的数组按照一定的顺序连接起来:

concatenate((a0,a1,......,aN),axis=0)

注意,这些数组要用()包括到一个元组中去。

除了给定的轴外,这些数组其他轴的长度必须是一样的。

import numpy as np
x=np.array([[0,1,2],[10,11,12]])
y=np.array([[50,51,52],[60,61,62]])
print(x.shape)
print(y.shape)
#结果:
(2, 3)
(2, 3)

默认沿着第一维进行连接:

z=np.concatenate((x,y))
print(z)
#结果:
[[ 0  1  2]
 [10 11 12]
 [50 51 52]
 [60 61 62]]

沿着第二维进行连接:

z=np.concatenate((x,y),axis=1)
print(z)
#结果
[[ 0  1  2 50 51 52]
 [10 11 12 60 61 62]]

注意到这里x和y的形状是一样的,还可以它们连接成三维的数组,但是concatenate不能提供这样的功能,不过可以这样:

z=np.array((x,y))
print(z)
#结果:
[[[ 0  1  2]
  [10 11 12]]

 [[50 51 52]
  [60 61 62]]]

事实上,Numpy提供了分别对应这三种情况的函数:

  • vstack

  • hstack

  • dstack

numpy内置函数

 

 

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流年ꦿ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值