数据分析实战45讲(三):Numpy

NumPy所提供的数据结构是Python数据分析的基础。

对于⼤部分数据分析应⽤⽽⾔,我最关注的功能主要集中在: ⽤于数据整理和清理、⼦集构造和过滤、转换等快速的⽮量
化数组运算。 常⽤的数组算法,如排序、唯⼀化、集合运算等。 ⾼效的描述统计和数据聚合/ 摘要运算。 ⽤于异构数据集的合并/连接运算的数据对⻬和关系型数据运算。 将条件逻辑表述为数组表达式(⽽不是带有 if-elif-else 分⽀的 循环)。 数据的分组运算(聚合、转换、函数应⽤等)

在NumPy里有两个重要的对象:ndarray(N-dimensional array object)解决了多维数组问题,而ufunc(universal function object)则是解决对数组进行处理的函数。

1.1 ndarray对象

ndarray实际上是多维数组的含义,⼀个通⽤的同构(所有元素是相同类型)数据多维容器。在NumPy数组中,维数称为秩(rank),一维数组的秩为1,二维数组的秩为2,以此类推。在NumPy中,每一个线性的数组称为一个轴(axes),其实秩就是描述轴的数量。每个元组都有一个shape(表示各维度大小的元组)和一个dtype(一个说明数组数据类型的对象)

#创建数组:最简单的办法就是使用array函数。它接受一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的numpy数组
import numpy as np
a=np.array([1,2,3])
b=np.array([1,2,3],[4,5,6],[7,8,9])
b[1,1]=10#更改[1,1]位置上的数为10
print(a.shape)
print(b.shape)
print(a.dtype)
print(b)
#返回(3L,);(3L,3L);int32;[[1,2,3][4,10,6][7,8,9]]

#除np.array之外,还有一些函数也可以新建数组。
#比如 zeros和ones,empty
np.zeros(3)#返回array[0.,0.,0.]
np.empty((2,3,2))#返回array([[[0.,0.],[0.,0.],[0.,0.]],[[0.,0.],[0.,0.],[0.,0.]]])
#arange是python内置函数range的数组版
np.arange(5)#返回array([0,1,2,3,4,5])

#数据类型默认为float64,可以通过astype方法将数据类型换掉
arr=np.array([1,2,3,4,5])
arr.dtype#返回int64
float_arr=arr.astype(np.float64)#将arr的数据类型转换为float64,并将该数组赋值给float_arr


#numpy数组的运算
#大小相等的数组之间的任何算术运算都会将运算应用到元素级,加减乘除不多做介绍
#大小相同的数组之间的比较会生成布尔值数组
a1=np.array([[1.,2.,3.],[4.,5.,6.]])
a2.np.array([[0.,4.,1.],[7.,2.,12.]])
a2>a1#返回array([[False,True,False],[True,False,True]])


数组常见的创建函数

#数组的切片
#跟列表最重要的区别在于数组切片是原始数组的视图,这意味着数组不会被复制,但对于数组而言,任何视图上的任何修改都会直接反映到源数组上
arr=np.arange(10)
#即array([0,1,2,3,4,5,6,7,8,9])
arr[5:8]=12#将第5到第7位的数改为12
arr_slice=arr[5:8]#arr_slice为array([12,12,12])
#当修改arr_slice的值时,变动也会体现在原始数组arr中:
arr_slice[1]=12345
arr#返回array([0,1,2,3,4,12345,12,12,8,9])
#切片[:]会给数组中的所有值赋值:
arr_slice[:]=64
arr#返回array([0,1,2,3,4,64,64,64,8,9)]


#高维数组的操作
arr2d=np.array([[1,2,3],[4,5,6],[7,8,9]])
arr2d[2]#返回array([7,8,9])
#可以传入一个逗号隔开的索引列表来选取单个元素
arr2d[0][2]#返回3
arr2d[0,2]#返回3
arr3d=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
arr3d[0]#返回array([[1,2,3],[4,5,6]])
arr3d[1,0]#返回array([7,8,9])
#在上面所有这些选取数组子集的例子中,返回的数组都是试图

#切片索引
arr#上面的arr为array([0,1,2,3,4,64,64,64,8,9])
arr[1:6]#返回array([1,2,3,4,64])
arr2d#返回array([[1,2,3],[4,5,6],[7,8,9]])
arr2d[:2]#返回array([[1,2,3],[4,5,6]]) 是沿着第0轴切片的,也就是说沿着一个轴向选取元素的,此语句可以被认为选取arr2d的前两行
arr2d[:2,1:]#返回array([2,3],[5,6]])
#索引与切片混用
arr2d[1,:2]#返回array([4,5]) 选取第二行的前两列
arr2d[:2,2]#返回array([3,6]) 选取第三列的前两行
#当然也可以通过切片对切片表达式进行赋值操作

结构数组

如果你想统计一个班级里面学生的姓名、年龄,以及语文、英语、数学成绩该怎么办?当然你可以用数组的下标来代表不同的字段,比如下标为0的是姓名、小标为1的是年龄等,但是这样不显性。

import numpy as np
persontype = np.dtype({
    'names':['name', 'age', 'chinese', 'math', 'english'],
    'formats':['S32','i', 'i', 'i', 'f']})
peoples = np.array([("ZhangFei",32,75,100, 90),("GuanYu",24,85,96,88.5),
       ("ZhaoYun",28,85,92,96.5),("HuangZhong",29,65,85,100)],
    dtype=persontype)
ages = peoples[:]['age']
chineses = peoples[:]['chinese']
maths = peoples[:]['math']
englishs = peoples[:]['english']
print np.mean(ages)#返回28.25
print np.mean(chineses)#返回77.5
print np.mean(maths)#返回93.25
print np.mean(englishs)#返回93.75

1.2 ufunc运算

通⽤函数(即 ufunc )是⼀种对 ndarray 中的数据执⾏元素级运算的函数。你可以将其看做简单函数(接受⼀个或多个标量值,并产⽣⼀个或多个标量值)的⽮量化包装器。
一元ufunc
二元ufunc
 
#创建两个数组
x1 = np.arange(1,11,2)#[1,3,5,7,9]初始值,终值,步长
x2 = np.linspace(1,9,5)#[1,3,5,7,9]初始值,终值,元素个数,默认包括终值
#算术运算
print np.add(x1, x2)#[2.,6.,10.,14.,18.]
print np.subtract(x1, x2)#[0.,0.,0.,0.,0.]
print np.multiply(x1, x2)#[1.,9.,25.,49.,81.]
print np.divide(x1, x2)#[1.,1.,1.,1.,1.]
print np.power(x1, x2)#[1.00000000e+00 2.70000000e+01 3.12500000e+03 8.23543000e+05 3.87420489e+08]
print np.remainder(x1, x2)/np.mod(x1,x2)#[0.,0.,0.,0.,0]
#统计函数
import numpy as np
a = np.array([[1,2,3], [4,5,6], [7,8,9]])
#amin()用于计算数组中的元素沿指定轴的最小值
print np.amin(a)#1 数组中全部元素的最小值
print np.amin(a,0)#[1,2,3] 沿着axis=0轴的最小值,axis=0轴是把元素看成了[1,4,7],[2,5,8],[3,6,9]三个元素,所以最小值为[1,2,3]
print np.amin(a,1)#[1,4,7] axis=1轴是把元素看成了[1,2,3], [4,5,6], [7,8,9]三个元素,所以最小值为[1,4,7]
print np.amax(a)#9 同理
print np.amax(a,0)#[7,8,9]
print np.amax(a,1)#[3,6,9]
#统计最大值与最小值的差
print np.ptp(a)#8
print np.ptp(a,0)#[6,6,6]
print np.ptp(a,1)#[2,2,2]
#统计数组的百分位数percentile()
#percentile()代表着第p个百分位数,p的取值范围是0-100
print np.percentile(a, 50)#5.0 p=50代表求平均值
print np.percentile(a, 50, axis=0)#[4.,5.,6.]
print np.percentile(a, 50, axis=1)[2.,5.,8.]
#统计数组中的中位数median(),平均数mean()
#求中位数
print np.median(a)#5.0
print np.median(a, axis=0)#[4.,5.,6.]
print np.median(a, axis=1)[2.,5.,8.]
#求平均数
print np.mean(a)[5.0]
print np.mean(a, axis=0)[4.,5.,6.]
print np.mean(a, axis=1)[2.,5.,8]
#统计数组中的加权平均值average() 默认情况下每个元素的权重是相同的
wts = np.array([1,2,3,4])#也可以指定权重数组
print np.average(a)#默认情况 2.5
print np.average(a,weights=wts)#3.0
#统计数组中的标准差std(),方差var()
print np.std(a)#1.118033988749895 计算每个数值与平均值之差的平方求和的平均值
print np.var(a)#1.25 方差的算数平均值 代表离散程度

Numpy排序

排序是算法中使用频率最高的一种,也是在数据分析工作中常用的方法。那么这些排序算法在NumPy中实现起来其实非常简单,一条语句就可以搞定。

axis=0代表跨行(纵向),行运算;axis=1代表跨列(横向),列运算

这里你可以使用sort函数,sort(a, axis=-1, kind=‘quicksort’, order=None),默认情况下使用的是快速排序;在kind里,可以指定quicksort、mergesort、heapsort分别表示快速排序、合并排序、堆排序。同样axis默认是-1,即沿着数组的最后一个轴进行排序,也可以取不同的axis轴,或者axis=None代表采用扁平化的方式作为一个向量进行排序。另外order字段,对于结构化的数组可以指定按照某个字段进行排序。

#排序
a = np.array([[4,3,2],[2,4,1]])
print np.sort(a) #[[2,3,4],[1,2,4]]
print np.sort(a, axis=None)#[1,2,2,3,4,4]
print np.sort(a, axis=0)#[[2,3,1],[4,4,2]] 
print np.sort(a, axis=1)#[[2,3,4],[1,2,4]]

1.3 练习

假设一个团队里有5名学员,成绩如下表所示。你可以用NumPy统计下这些人在语文、英语、数学中的平均成绩、最小成绩、最大成绩、方差、标准差。然后把这些人的总成绩排序,得出名次进行成绩输出。

import numpy as np
arr_dtype=np.dtype({
    'names':['name','yuwen','yingyu','shuxue'],
    'formats':['S32','i','i','i','i']})
score=np.array([("zhangfei",66,65,30),("guanyu",95,85,98),("zhaoyun",93,92,96),("huangzhong',90,88,77),("dianwei",80,90,90)],dtype=arr_dtype)
yuwen=score[:]['yuwen']
yingyu=score[:]['yingyu']
shuxue=score[:]['shuxue']
#平均
print("语文平均: ",np.mean(yuwen))
print ("数学平均: ",np.mean(shuxue))
print ("英语平均: ",np.mean(yingyu))
#最小
print("语文最低: ",np.amin(yuwen)
print("数学最低: ",np.amin(shuxue))
print ("英语最低: ",np.amin(yingyu))
#最大
print("语文最高: ",np.amax(yuwen)
print("数学最高: ",np.amax(shuxue))
print ("英语最高: ",np.amax(yingyu))
#方差
print("语文方差: ",np.std(yuwen)
print("数学方差: ",np.std(shuxue))
print ("英语方差: ",np.std(yingyu))
#标准差
print("语文标准差: ",np.var(yuwen)
print("数学标准差: ",np.var(shuxue))
print ("英语标准差: ",np.var(yingyu))
#总成绩排序
score[:]['total']=score[:]['yuwen']+score[:]['yingyu']+score[:]['shuxue']
print( "排序",np.sorted(score,order='total'))

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值