NumPy基础之大作业(Iris数据分析)

@[云好晕啊]学习笔记

大作业

【声明:本章所有内容都是通过一个程序完成的,所以每个小问题中的代码存在数据复用以及后面的代码没有导入相应的库情况】

 本次练习使用的是 鸢尾植物数据集。Iris也称为鸢尾花卉数据集,包含了三类不同鸢尾属植物:Iris Setosa、Iris Versicolour、Iris Virginica。每类包含50个样本。整个数据集150个样本,每个样本包含4个特征分别为:

  • sepal_lenth(花萼长度)
  • sepal_width(花萼宽度)
  • pepal_length(花瓣长度)
  • pepal_width(花瓣宽度)

以上特征单位均为cm。
部分数据

1、导入鸢尾植物数据集,保持文本不变

【知识点:输入输出】

  • 如何实现导入存在数字与文本的数据集?

【答案】
 因为本次使用的鸢尾植物数据集是sklearn.dataset中自带的数据,所以本次数据的导入是直接通过相应函数:

  •  sklearn.datasets.load_iris()
    

但是因为这个数据集中包含很多部分内容,包括属性数据值,所属种类等等,所以还需要进行预处理以获得相应格式的分析数据。
具体思路是首先获取属性类数据iris.data,再考虑添加相应的分类数据,因为是按照顺序排列的,所以可以通过for循环实现分类数据构造,再进行连接两个数据集。将结果存入并加上行名称。接着就是对文本文件的读出。
代码:

import numpy as np
from sklearn import datasets

#导入库中数据集
iris=datasets.load_iris()
#将鸢尾四种类别数据转换为数组
iris_data=np.array(iris.data)
#创建鸢尾品种数组
k=np.array(['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'])
#构建种类数组p
p=np.array([])
#前50个数据属于setosa类,50-100属于versicolor类,后50属于virginica
for i in range(150):
    p=np.append(p,k[i//50])
#数据连接
p=np.array(p).reshape(150,1)
iris_data=np.append(iris_data,p,axis=1)

#保存为iris数据为文本文档
np.savetxt('iris.txt',iris_data,fmt = '%s',delimiter=',',newline='\n',
          header='sepallength,sepalwidth,petallength,petalwidth,species')

#输入输出
print('导入鸢尾属植物数据集')

outfile=r'iris.txt'
iris_data=np.loadtxt(outfile,dtype=object,delimiter=',',skiprows=1)
print(iris_data[0:10])

输入输出

2、求出鸢尾属植物萼片长度的平均值、中位数和标准差

【知识点:统计相关】

  • 如何计算numpy数组的均值,中位数,标准差?
    【答案】
     计算一个数组中的均值可以使用mean()average()函数;计算中位数可以使用median()percentile(),后者需要指定位置在50;计算标准差可以使用定义法std()函数。
    代码:
#统计相关
print('求萼片长度平均值、中位数和标准差(第一列数据)')
sepalLength=np.loadtxt(outfile,dtype=float,delimiter=',',skiprows=1,usecols=[0])
print('前10个萼片长度数据:','\n',sepalLength[0:10])

print('萼片长度平均值:',np.mean(sepalLength),'\t',np.average(sepalLength))
print('萼片长度中位数:',np.median(sepalLength),'\t',np.percentile(sepalLength,50))
print('萼片长度标准差:',np.std(sepalLength))

属性

3、创建一种标准化形式的鸢尾属植物萼片长度,使得值介于0与1之间

【知识点:统计相关】

  • 如何标准化数组?

【答案】
 标准化数组可以通过以最小值为0起点,极差作为整个长度标准区间来实现
代码:

#统计相关
print('创建标准化的鸢尾植物萼片长度,使得值位于0-1之间')
#方法一:
#先求最大最小边界值
aMax=np.amax(sepalLength)
aMin=np.amin(sepalLength)
x=(sepalLength-aMin)/(aMax-aMin)
print('方法一前10个标准化数据:',x[0:10])
#方法二
x=(sepalLength-aMin)/np.ptp(sepalLength)
print('方法二前10个标准化数据:',x[0:10])

标准化数组

4、找到鸢尾属植物萼片长度的第5和第95百分位数

【知识点:统计相关】

  • 如何找到numpy数组的百分位数?

【答案】
 寻找一个数组中的百分位数可以使用percentile()函数,需在第二个参数指定需要寻找的位数,可以以数组形式传递参数,返回多个分位数。
代码

#统计相关
print('找到鸢尾属萼片长度的第5和第95百分位数')
x=np.percentile(sepalLength,[5,95])
print('鸢尾萼片长度第5和第95分位数据:',x)

百分位数

5、把iris数据集中的20个随机位置修改为np.nan值

【知识点:随机抽样】

  • 如何在数组中随机位置修改值?

【答案】
 随机产生数据有很多种方式,考虑到本次是随机产生索引位置,应该为整数,所以可以使用randint()函数,它可以产生指定区间均匀分布的整数;还可以使用choice()函数直接在数据集进行随机选择20个位置。
代码:

#统计相关
print('创建标准化的鸢尾植物萼片长度,使得值位于0-1之间')
#方法一:
#先求最大最小边界值
aMax=np.amax(sepalLength)
aMin=np.amin(sepalLength)
x=(sepalLength-aMin)/(aMax-aMin)
print('方法一前10个标准化数据:',x[0:10])
#方法二
x=(sepalLength-aMin)/np.ptp(sepalLength)
print('方法二前10个标准化数据:',x[0:10])

#统计相关
print('找到鸢尾属萼片长度的第5和第95百分位数')
x=np.percentile(sepalLength,[5,95])
print('鸢尾萼片长度第5和第95分位数据:',x)

#统计相关
print('把iris_data数据集中第20个随机位置修改为np.nan值')
#方法一
#获取鸢尾数据集大小
i,j=iris_data.shape
np.random.seed(202011)
iris_data[np.random.randint(i,size=20),np.random.randint(j,size=20)]=np.nan
print('方法一前10个修改后的数据:',iris_data[0:10])

#方法二
iris_data=np.loadtxt(outfile,dtype=object,delimiter=',',skiprows=1)
iris_data[np.random.choice(i,size=20),np.random.choice(j,size=20)]=np.nan
print('方法二前10个修改后的数据:',iris_data[0:10])

随机抽样

6、在iris的sepallength中查找缺失值的个数以及位置

【知识点:逻辑函数、搜索】

  • 如何在numpy数组中找到缺失值的位置?

【答案】
 查找缺失值及其位置可以通过isnan()函数来实现,该函数是对每一个位置值进行判断是否确实,是则返回True反之返回False,这样可以直接通过sum()实现计数功能。而要找到具体位置可以通过逻辑查找函数where()来实现。
代码

#逻辑函数,搜索
print('在iris_data数据集找那个的sepallength查找缺失值个数以及位置')
sepalLength=iris_data[:,0].astype('float')
x=np.isnan(sepalLength)
print('总共缺失值个数:',sum(x))
print('缺失位置:',np.where(x),'\t',x)

查找

7、筛选具有sepallength<5.0并且petallength>1.5的iris数据行

【知识点:搜索】

  • 如何根据两个或多个条件筛选numpy数组?

【答案】
  在numpy中有各种逻辑函数,包括与、或、非等,根据题目条件可知需要通过逻辑来实现,即调用logical_and()函数来实现判断,接着通过where()函数来实现数据的查找。
代码

#搜索
print('筛选合适的值')
#读取前四列数据,float类型
iris_data=np.loadtxt(outfile,dtype=float,delimiter=',',skiprows=1,usecols=[0,1,2,3])
#获取萼片长度数据以及花瓣长度数据
sepalLength=iris_data[:,0]
petallength=iris_data[:,2]
#进行筛选数据
index=np.where(np.logical_and(petallength>1.5,sepalLength<5.0))
print('符合筛选条件的值:',iris_data[index])

筛选

8、选择没有任何nan值得iris行

【知识点:逻辑函数、搜索】

  • 如何从numpy数组中删除包含缺失值得行?

【答案】
 首先判断缺失值还是需要调用isnan()函数,因为题目要求是行,即一行都不能有缺失值,这时可以考虑到sun()进行行计数,通过逻辑判断值为0即为符合条件的行。
代码

#逻辑函数,搜索
print('选择没有nan值得行')
#随机将20个数据置为nan
iris_data[np.random.randint(i,size=20),np.random.randint(j-1,size=20)]=np.nan
#筛选数据
x=iris_data[np.sum(np.isnan(iris_data),axis=1)==0]
print('没有缺失数据的前10行:',x[0:10])

筛选

9、计算iris中sepallength和petallength之间的相关系数

【知识点:统计相关】

  • 如何计算numpy数组两列之间的相关系数?

【答案】
 计算相关性,我们可以直接调用corrcoef()函数来计算,也可以通过定义来分步计算——先求两列均值,在计算两者的协方差以及各自的标准差,最后相除得到结果。
代码:

#统计相关
print('计算sepallength和petallength两列相关系数')
#读取前四列数据,float类型
iris_data=np.loadtxt(outfile,dtype=float,delimiter=',',skiprows=1,usecols=[0,1,2,3])
#获取萼片长度数据以及花瓣长度数据
sepalLength=iris_data[:,0]
petallength=iris_data[:,2]
#方法一
#计算两列数据均值
m1=np.mean(sepalLength)
m2=np.mean(petallength)
#计算协方差矩阵
cov=np.dot(sepalLength-m1,petallength-m2)
#计算两列数据标准差
std1=np.sqrt(np.dot(sepalLength-m1,sepalLength-m1))
std2=np.sqrt(np.dot(petallength-m2,petallength-m2))
print('相关系数为:','\n',cov/(std1*std2))

#方法二
x=np.mean((sepalLength-m1)*(petallength-m2))
y=np.std(sepalLength)*np.std(petallength)
print('相关系数为:',x/y)

#方法3
x=np.cov(sepalLength,petallength,ddof=False)
y=np.std(sepalLength)*np.std(petallength)
print('相关系数:',x[0,1]/y)

相关系数

10、找出iris是否有任何缺失值

【知识点:逻辑函数】

  • 如何查找给定数组是否具有空值?

【答案】
 查找缺失值使用isnan()函数来实现,在将返回后的结果通过all()函数来实现逻辑判断。
代码:

#逻辑函数
print('找出数据集是否有任何缺失值')
x=np.isnan(iris_data)
print('是否有缺失值:',np.any(x))

缺失值判断

11、在numpy数组中将所有nan的值替换为0

【知识点:逻辑函数】

  • 如何在numpy数组中用0替换所有缺失值?

【答案】

 其实这道题思路与上面的一道题基本一致,首先是通过isnan()返回每个位置缺失情况,接着通过逻辑函数找到位置进行赋值替换即可。
代码:

#逻辑函数
print('将数组中所有出现的nan替换为0')
#随机将20个数据置为nan
iris_data[np.random.randint(i,size=20),np.random.randint(j-1,size=20)]=np.nan
#寻找值为nan的数据位置并且置为0
iris_data[np.isnan(iris_data)]=0
print('修改后前10行数据:',iris_data[0:10])

替换

12、找出鸢尾属植物种中的唯一值和唯一值出现的数量

【知识点:数组操作】

  • 如何在numpy数组中查找唯一值的计数?

【答案】
 numpy中有一个绝佳的函数来实现唯一值计数的功能,那就是unique()函数,它首先返回的是排序后且没有重复数据的数组,要实现计数功能可以指定return_counts参数为True来返回各个数据的数量,除此之外还可以指定return_indexreturn_inverse来指定索引位置。
代码:

#数组操作
print('找出鸢尾数据集中每一个值和出现的数量')
iris_data=np.loadtxt(outfile,dtype=float,delimiter=',',skiprows=1,usecols=[0,1,2,3])
x,p=np.unique(iris_data,return_counts=True)
print('每一个值和相应数量:')
print(x,'\n',p)

唯一值

13、将iris的花瓣长度以形成分类变量的形式显示。

定义:Less than 3 -->‘small’;3-5–>'medium;>=5–>‘largr’。
【知识点:统计相关】

  • 如何将数字转换为分类(文本)数组?

【答案】
 要将数组中数字转换为文本(分类),我们可以通过字典映射方式来实现。具体是先通过bin()函数对区间进行分段,接着通过digitize()函数返回每个数据所在分段,接着我们可以通过分段位置建立字典,位置作为键值,文本作为值。依次循环就可以实现转换。
代码:

#统计相关
print('将数字转换为文本数组')
iris_data=np.loadtxt(outfile,dtype=float,delimiter=',',skiprows=1,usecols=[0,1,2,3])
#将数据分段表示
petal_length_bin=np.digitize(iris_data[:,2],[0,3,5,10])
#映射字典
label_map={1:'small',2:'medium',3:'larger',4:np.nan}
petal_length_cat=[label_map[x] for x in petal_length_bin]
print('前10个转换数据:',petal_length_cat[0:10])

映射

14 在iris中创建一个新列volume

volume是(pi * petallength^2)/3。
【知识点:数组操作】

  • 如何从numpy数组的现有列创建新列?
    【答案】
     生成一个单独的新列很简单,本题主要是考察数组之间的连接问题,对于连接我们可以使用很多方法,包括concatenate()函数、stack()函数、vstack()函数、hstack()函数等,前两个可以指定轴向,默认为水平。
    代码:
#数组操作
print('创建新列,其中volume是(pi*petallength*sepallength^2)/3')
#读取数据集
iris_data=np.loadtxt(outfile,dtype=object,delimiter=',',skiprows=1)
#读取sepallength数据并转换为float类型
sepalLength=iris_data[:,0].astype(float)
#读取petallength数据并转换为float类型
petallength=iris_data[:,2].astype(float)
volume=(np.pi*petallength*sepalLength**2)/3
volume=volume[:,np.newaxis]
#连接数据
iris_data=np.concatenate([iris_data,volume],axis=1)
print('前10行数据:',iris_data[0:10])

插入新列

15、随机抽取鸢尾属植物种类,使得Iris-setosa的数量是Iris-versicolor和Iris-virginica数量两倍

【知识点:随机抽样】

  • 如何在numpy中进行概率抽样?

【答案】
 提到概率抽样我们就可以想到random中的choice()函数,其中可以指定各个项的概率,依据题意我们应该依次指定概率为[0.25,0.5,0.25]
代码:

#随机抽样
print('随机抽样')
species=np.array(['Iris-setosa','Iris-versicolor','Iris-virginica'])
species_out=np.random.choice(species,10000,p=[0.5,0.25,0.25])
print('随机抽取情况:',np.unique(species_out,return_counts=True))

随机抽样

16、根据sepallength列对数据集进行排序

【知识点:排序】

  • 如何按列对2D数组进行排序?

【答案】
 在numpy中,排序有两种返回形式,一种是直接返回按值排序后的数组,使用sort()函数;另外一种是返回一个索引数组,通过索引数组可以的到排序后数组,这是通过argsort()函数来实现的。
代码:

#排序
print('根据sepallength列排序')
#读取数据集
iris_data=np.loadtxt(outfile,dtype=object,delimiter=',',skiprows=1)
#读取sepallength数据并转换为float类型
sepalLength=iris_data[:,0].astype(float)
index=np.argsort(sepalLength)
print('排序后前10行数据:',iris_data[index][0:10])

排序

17、在鸢尾属植物数据集中找到最常见的花瓣长度值

【知识点:数组操作】

  • 如何在numpy数组中找到出现次数最多的值?

【答案】

 在第12题中,我们提到unique()函数,显然这里也可以使用,因为该函数在我们指定参数return_counts=True后可以实现各个值计数。接着通过argmax()函数返回最大值索引,这样就可以得到相应的值,通过amax()获得该值出现的次数。
代码:

#数组操作
print('在数据集中找到最常见花瓣长度值')
petallength=iris_data[:,2]
vals,counts=np.unique(petallength,return_counts=True)
print('最常见花瓣长度:',vals[np.argmax(counts)])
print('最常见花瓣的数量:',np.amax(counts))

最大值

18、在鸢尾属数据集的petalwidth中查找第一次出现的值大于1.0的位置。

【知识点:搜索】

  • 如何找到第一次出现大于给定值的位置?

【答案】
 查找大于某一定值位置我们可以通过where()来返回满足条件值的索引数组,因为查找是按顺序进行的,所以只要获取索引数组中第一个值即是我们要找的。
代码:

#搜索
print('在数据集中找出petallength中第一次出现值大于1.0位置')
#读取petalwidth数据
petalwidth=iris_data[:,3].astype('float')
#筛选数据
index=np.where(petalwidth>1.0)
print('出现大于1.0值得位置:',index)
print('第一次出现大于1.0的位置:',index[0][0])

查找

总结

 本次numpy组队学习在写完这篇博客也就预示着结束了,怎么说了,还是有收获的,其中无论是编写代码还是写博客也花了大量时间,自己确实还有很多需要提高的地方。不多说了,祝大家都能有有所收获,有一个光明的未来!

  • 19
    点赞
  • 104
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值