第四课剩余内容:
• 0. 导入 NumPy 包
• 1. 创建 NumPy 数组
• 2. 索引和切片
• 3. 读取文件
• 4. 布尔型索引
• 5. 数组的运算
• 6. 常用函数举例
小括号:方法和含义,自定义函数
方括号:元组,字典等序列型的
3. 读取文件
这一课的“读取文件”,在获取红酒品质数据这一步上,就折腾了挺长时间的。我先看老师的示范,知道有一个几千行的红酒品质数据。然后不知道为什么有一种侥幸心理,按着老师的代码打一遍,妄想那个几千行的大数据能够自动出现在我的jupyter里面😂嗯,果然是丧心病狂。
结果很显然:
第一反应就是,我去求助吧!
“做伸手党还是不是太好。自己再找找吧!”
然后傻乎乎再听老师讲,这个数据比较出名,来自于机器学习的什么CI,我就上网Google了,最后找到这样的页面:
好像并没有找到那个红酒品质数据包的下载地址。一拍脑袋!啊!我们有课前预习资料啊!我记得。。好像有!在新生大学这门课里面,作业内容有预习资料,打开的时候只是怕老师会删掉这部分内容。没想到还在!
路径如下图:
我去作业讨论区看了一下,有人对数据下载这个问题也有疑惑:
按照老师说的,进入文件后找到raw,然后右键选择“链接存储为”。这时候文科生的疑惑又来了:这是一个csv文件,Python里面都是代码,能兼容吗?所以又去看一遍回放,老师是怎么做的。
这个红酒品质数据,看起来就是一个文档啊!我新建一个文档,直接把下载在桌面的这个数据文档拉到这个新建文档中,(我用的是mac,不知道windows数据是不是也是拉过去就能直接存储了)本来在桌面上打开是表格的文档瞬间变成几千行一串一串的数据了。这时候觉得挺像样的,应该没有错了。
然鹅,并没有什么卵用。。。我试了一遍又一遍,都是红色警报,所以不是哪里打错了,是打的内容就有问题
我被卡在这里很久,早上起来码就卡住,然而只是自己继续跟着打,并没有更高效的办法,解决,中午休息的时候拿出来就想着可能是旧的文档卡住了,重新开了一个文档重新打,还是这样。晚上实在受不了这低效率了,截图去群里:
中途restart,前面定义过的值不能继续使用,所以要重新定义。
中途restart,前面定义过的值不能继续使用,所以要重新定义。
中途restart,前面定义过的值不能继续使用,所以要重新定义。
所以我重新赋值 import numpy as np,然后能够用了。。。老泪纵横啊
想要知道这堆数据有多少行和列,是有办法显示出来的:
这是一堆有1599行,12列的数据。
也是有64位的浮点的浮点型数据。
提取里面的某属性的数据。
4. 布尔型索引
• 之前的切片索引方法是通过指定行或列的位置来取一个数组的一部分
• 顾名思义,布尔索引是通过一个布尔型数组来确定所需要的行或者列的位置
• 当行或列位置对应的布尔索引为True的时候,我们会保留这个行或列。反之,当对应的布尔索引为False的时候,则不选取。
上面的两个截图,是在第6条运行行的基础上实行的,也就是在数据切片上面进行数据切片,这里要找的是6中切片的评分大于5的红酒数据。我们可以看到 7 中,有符合和不符合的。在 9 中定义mask,然后用 wine(mask) 得出符合条件的数据。
这个顺序是先定义一个布尔型的数组,然后用 mask 来重新定义,得出具体数据。
我们来一个多条件的索引,不禁评分大于5,还有酒精度的评选:
上面两个例子,其实是自己没有熟悉 mask 的用法。先定义出一个布尔型函数,然后直接用 mask 赋值。得出的是上面“评分大于5的红酒数据”的例子结果,因为 mask 在上面定义了,我没有进行重新定义,只能共享上面的数据了。看到和老师的例子显示不一样,我才重新认真看一遍不同。
正确例子中,还是用布尔型函数先定义,然后重新赋值 mask ,这个时候用的数据就是更新过后的数值了,也就是加上了 “且酒精度大于10的” 这个条件。然后用 wine[mask] 得出结果。
这个例子里面,由于运算优先级的考虑,在两个不等式旁边加上圆括号,括号中的不等式优先级更高,也就是先进行运算。用 & 来连接两个不等式,结果就是“且”的关系。
5. 数组的运算
5-1. 数组与单个数之间的运算
这用回了《文科生学Python数据分析系列 7》 里面的例子,因为我关掉重新打开,所以直接像老师那样打 mat ,并不能得到识别。所以只能重新定义 mat 。然后才能使用。
19 是 mat 除以2,整个数组和单个数的计算,看起来不是很难。
20 是 mat 整个数组进行平方运算,得到的结果。
22 是 mat 整个数组先加100,然后除以100。这里又用到了圆括号,我们前面讲到,括号表示优先级,所以是先加后乘。
来个实用情景的例子:
第2列数据就是它的评分,所以只用第二列的数据。
以上是数组的运算,我们试试要是用回列表的方式进行运算,是怎样的呢?
• Numpy 数组的任何算数运算,都会将运算运用到元素级别。
• 这样的矢量化运算是NumPy 数组的优势, Python列表要实现这一操作就需要编写循环。
评分的列表数据:
定义 score_list ,然后用 list 函数强制转换成列表,输出的结果是用方括号包住的。而上面的数组,同一组数据,方括号外面还有一对圆括号。
那当我们想要用整个列表的数据都乘于 10 ,怎么做呢?
先试试数组的办法,直接乘以 10 :
得出的结果是整个列表的数据,重复了 10 遍。并不能自己叠加计算。所以列表相乘啊,不能用数组那种简单快捷的方法。
用的是循环语句。首先定义一个新的列表 new_list ,初始化列表的元素。
然后用 for 循环,赋值 s ,遍历 score 列表中的所有元素。
然后新定义的列表,用append这个语法,可以在新的列表中追加一个新的元素。也就是不断相乘,归类。得出一个新的列表。
得出的结论是:数组进行运算,比列表的步骤简单,效率更高。
5-2. 数组与数组之间的运算
• 两个行列数相符的数列可以进行运算
• 运算操作将应用到数列中对应的每一个元素
来吧,数组和数组之间的运算,例子:
29 和 30 都是同样的结果,不同的方法
31 是数组之间的相乘。
老师说这是属于“广播”的内容,比较复杂,就略过了。只听到前面的 wine 是二维数组,后面的 wine[0] 是一个一维数组。这样的计算就是 广播。
6. 常用函数举例
这里的例子中,还是红酒数据的数组切片。第一列是PH值,第二列是酒精度,第三列是评值的评分。
计算红酒数据属性的平均值。读题知道我们需要先有这个属性的总数,然后知道这个属性里面的个数,才能算出平均值。
用 sum 来定义总和,里面的 axis=0 ,(axis,中文意思是“轴”)我的理解是这个属性所在的位置,其实也就是这一列的数据定位。因为我们在前面说过,列对应的是0轴,行对应的是1轴。
np.sum(wine.axis=0) 这句代码的意思就是 在np这个类型里面,wine 这个数据切片中,每一列的数据总和 sum 是多少。
每一列的总和算出来了,还有就是这些总和相加的个数有多少。很明显,就是行数的数量,用 len 来定义长度,也就是个数的数量。得出的结果就是每一列的数据的平均数,也就是每一个属性的平均值。
老师说,用 mean 来定义函数,也能得到一样的平均值。惊讶了,查了字典才知道原来 mean 除了以前了解的“吝啬”和“意味”的意思之外,还有“均值”的含义。。。长见识了。
这里要吐槽一下我们回放的质量啊,只有 “mean也有一样的功能”,然后就被切断了,听不到后面是什么。
在数组中找最大值和最小值的语法也是用 max 和 min ,这个例子中已经把范围定在了一列中,也就是查找每一个属性中的最大值和最小值。
• NumPy 数组比 Python 列表效率更高
数组和列表都有max函数可以找到最大值,我们来看下他们的运算速度。
鹅。。。老师为了显示Numpy数组比Python列表的运算效率高,给出了上面这个例子。计算效率其实就是计算的运行时间。又有新名词,觉得不是很好理解,只知道好像是用 %timeit 来计算速度。。
首先是用随机数生成的方法,这个时候用 random ,随机生成10000个数字,然后将数组转换成列表,用 random_list 。列表的在 40 中,也就是得出来同样的数据,Python列表运算需要 237 微秒,Numpy数组需要 6.26 微秒。所以很明显,谁赢了呢?
又要拿出来分解一下。定义一个随机函数用 random_arr ,在 39 中,两条语句都是为了下面的运算做准备的。计算 Python列表之前,就需要将定义好的函数强制转换成列表的类型,也就是 random_list ,但是在 Numpy数组的运算中,用初始定义好的 random_arr 就可以了。不过要在前面加一个前缀 np 。
继续例子:
这是在 wine 这个切片数组中,第一列表示PH值的数据,进行从小到大的排序。这里用的是 sort 。
继续例子:
说实话,看第一遍这个例子我不知道在讲什么。老师把屏幕拉回前面的这个 wine 的值:
然后我看了一下,定义的范围在第二列。
读题,“ 哪几种评分 ” 和 “ 不重复的打分 ” 貌似是在讲同一个东西。这时候才想起来了,第2列表示的是对红酒品质的评分,是在说这个切片数据中这一列的评分,有几档,和分别是什么数值。
这里用的是 unique 。
继续例子:
看到循环就有点懵圈。因为需要看明白这里面的逻辑,一句废话和多余的步骤都没有。这个例子是在评分数据中,用一个标准,就是数据=5 为界限,把数据分为Good 和 Bad。
循环开始之前需要初始化,把new设为一个新的数值。在 wine 这个数据切片中,第2列的范围内,用 s 来遍历整列的数据,要是遇到 大于5 的值,就把这个大于5 的数据变成 “Good” 来重新表示这个数据,要是小于等于5 的话,用 “Bad” 来重新赋值这个数据。
append 这个词,英语字典说 附加 , 贴上, 添加 的含义。所以可以理解为,在用 s 遍历整列数据时,在数据大于5时,就添加 Good 。
我理解的是 44 和 45 是一样的,用的是循环语句,Python列表的使用。
46 中是使用Numpy数组来进行运算的,语句清晰简短了不少。用 wine[:,2] > 5 来表示一个判断语句,要是成立的话,就是前面的 Good,要是不成立,就是后面的 Bad。这里简短到,没有if 和else。判断语句成立就是取前面的值,不成立就取后面的值。使用 where 就是对范围内的每一个参数进行判断操作。
作业4-2:
给出一组学生姓名,和他们对应的成绩,存储在下方数组中。请计算以下问题:
1 找出不及格的学生姓名(提示:使用布尔型索引)
2 找出最高分、最低分,平均分数
3 将数值成绩转化成字母成绩,大于等于90分为A, 70-89分为B,小于70分为C
In [68]:
names = np.array(["Xiao Ming","Xiao Zhang","Xiao Gang","Xiao Hong","Xiao Pang","Xiao Wu","Xiao Dai",
"Xiao Qian","Xiao Fan","Xiao Wang"])
scores = np.array([ 91, 68, 84, 55, 95, 81, 67, 82, 86, 78])
这个作业。。今晚我再做。
昨天以为能把这部分内容码完的,没想到到了12点半还没结束,已经不能熬夜了,所以今天早上早点起来继续码。昨天以为这篇要超3000字,没想到此刻已经4000+了。怎么越写越长了呢😂
最后附点资料给大家。有同学问到那么多已经被赋值过的函数我们都不知道啊,老师说用多就会熟练的。我在我们的《利用Python进行数据分析》这本书上翻了一下,就找到这两节课学的一些函数了:
大家可以善用资源哟!
还有讨论区有人问数据资料可以去哪里找,徐老师回答如下:
一般网上有一些开放的数据集,国外的较多,比如
著名的UCI机器学习数据集 【 http://archive.ics.uci.edu/ml/ 】
Kaggle 竞赛数据 【 https://www.kaggle.com/datasets 】
或者政府提供的开放数据,比如
美国 DATA.GOV 【 https://www.data.gov 】
纽约 NYC OpenData 【 http://opendata.cityofnewyork.us 】
The Humanitarian Data Exchange 【 https://data.humdata.org 】
国内的比较少,比如聚数力 【 http://dataju.cn/Dataju/web/dataDescriptionAndDataset 】
还有收费的数据堂
如果要获取网页数据,可以自己编写爬虫工具来采集
有些网站提供数据的API接口,比如微博,但是数量和频率非常有限制
想要获取理想的数据本来就不是一件容易的事情,特别是在数据已被当成宝藏的今天
嗯,今晚做作业,和预习明晚的课程啦!!!!准备上班去~🤓