跳到正文 Lab Week 2 Summary · Jimmy Huang's Blog
、
describe()
看数据
用 isna()、 dropna()、 fillna() 处理缺失值
理解为什么 Pandas 的向量化操作比 for 循环快很多
Task 0: 环境准备与 Pandas 热身 这个 Task 先做最基础的准备,让你对 DataFrame 有一个直观认识。
Step 0.1:导入本周会用到的库 把 Pandas 和 Numpy 导入进来,后面所有操作都要基于这两个库。
Step 0.2:创建一个最简单的 DataFrame 这一步是为了先建立“DataFrame 就是一张二维表”的感觉。
哪怕你只给一列数据,它也会变成一张表,而不是普通列表。
Step 0.3:按索引访问数据 因为你后面不只是“看表”,还要学会精准地取到某几行、某几列。
Step 0.4:给列或索引补充说明 Pandas 里不只是“数据本身”,行索引、列索引也都是结构的一部分。
Step 0.5:创建带日期索引的 DataFrame(可选但建议做) 创建一个 7 行 5 列的随机数据表,并用日期做索引。
这是为了让你知道, DataFrame 不只是“纯数字表”,它可以有:
一个更直观的例子
Task 1: 读取并探索 UFO 示例数据 从 URL 读取一个现成 CSV
看数据有多少行列
看列名、数据类型、统计信息
练习取前几行、后几行、指定列、条件筛选
理解 loc 和 iloc 的区别
Step 1.1:读取 UFO 数据集 把 UFO sightings 数据读成一个 Pandas DataFrame。
因为真实的数据 wrangling,第一步通常就是把 CSV 读进来。
应成功得到一个名为 ufo 的 DataFrame。
Step 1.2:先看这张表的整体结构
Step 1.3:看具体内容长什么样 你不能只知道“有多少行列”,还要真正看一下数据内容长什么样,才知道后面怎么清洗。
Step 1.4:做条件筛选 按条件筛选州(State)是否等于 NJ 的记录。
还可以使用 <, >, <=, >= or != (not equal).
Step 1.5:理解 loc 和 iloc这是 Pandas 里最容易混淆、也最常被问的基础点之一。
这个实验问题可以这样回答 loc 是按行列标签(label)来取值,适合你已经知道列名或索引名的时候使用。
iloc 是按整数位置(integer location)来取值,适合按第几行第几列来切片。
Task 2: 连接 Google Drive 并完成 xmart 数据基础探索 这个 Task 是第一个真正要你自己动手做的小练习。
挂载 Google Drive
找到共享盘里的 xmart.csv
读入数据
回答记录数、属性数、属性名、数据类型、数据集大意
Step 2.1:挂载 Google Drive 把你的 Google Drive 挂载到 Colab 环境里。
因为这周 notebook 里的数据文件不全都在公开 URL 上,有些在共享盘里。
运行后会跳出授权链接,登录 Monash 账号并授权后,左侧文件面板里应该能看到 drive。
截图占位:这里放 Google Drive 挂载成功后的截图
Step 2.2:先确认共享盘路径是否正确 Shared Drive 名字对不对
Week2 / week2 文件夹大小写对不对
目标文件到底在哪个目录
这份 notebook 里已经出现过 FileNotFoundError,最常见原因就是:
如果你报的是 FileNotFoundError,按这个顺序查:
Drive 是否真的挂载成功
左侧文件面板里是否看到 Shareddrives
共享盘名是否真的是 FIT5196_S1_2026
文件夹到底叫 Week2 还是 week2
文件名是否确实是 xmart.csv
Step 2.3:读取 xmart 数据 如果上面路径报错,再根据你刚刚 ls 的结果改成正确路径,例如:
skiprows=1 说明原始文件第一行可能不是正式表头,或者老师希望你从第二行开始读。
截图占位:这里放 xmart.head() 的截图
Step 2.4:查看 xmart 的基础信息 有多少条记录
有多少个属性,属性名是什么
每个属性是什么数据类型
不看描述,你能不能自己概括这份数据在记录什么
Step 2.5:整理成可交的回答草稿
Task 3: 处理缺失值(Missing Values) 检查哪些列有缺失值
看每列缺失了多少
理解“直接删掉”与“补值”两种思路
知道什么时候不能乱填 0
Step 3.1:检查 UFO 数据中的缺失值
Step 3.2:方法一——直接删除缺失值行 创建一个新 DataFrame ufo1,只保留所有列都完整的记录。
这份示例数据里,原表有 18241 行,而至少有一个缺失值的行有 15755 行。
它只是最简单的一种选择,代价通常是数据量大幅缩水。
Step 3.3:方法二——尝试填补缺失值 Pandas 虽然允许你这么干,但并不代表这样填是合理的。
因为 Colors Reported、 Shape Reported 这类列是文本型/类别型字段。
你把它们填成 0,技术上能运行,语义上却非常奇怪。
Step 3.4:给文本列填一个更合理的占位值 复制一份数据,在 Colors Reported 这一列里把空值补成 'BLUE'。
之前 Colors Reported 为空的位置,现在会出现 'BLUE'。
Task 4: 新增列、合并列、比较性能、删除冗余列 新建空列
先补全缺失的 City
把 City 和 State 合并成一个新列
比较向量化写法和 for 循环写法
删除重复信息列
Step 4.1:先创建一个新列 在 ufo4 里新增一列 place,先让每一行都放空字符串。
Step 4.2:先处理 City 列的缺失值 如果 City 里还有空值,合并出来的结果就可能是空的或者不完整。
Step 4.3:用向量化方式合并 City 和 Stateufo4['City'] 是城市名
', ' 是中间分隔符
ufo4['State'] 是州名
三者逐行拼接,得到完整地点
Step 4.4:用 for 循环实现同样的事(用于对比,不是推荐写法) 手动逐行循环,把 City 和 State 拼成 address。
不是因为它更好,而是为了和前面的向量化方法做性能对比。
Step 4.5:比较两种写法的速度 Pandas 的列操作通常远快于 Python 层的逐行循环。
向量化写法大约是 毫秒级
for 循环写法大约是 秒级
Step 4.6:删除重复信息列 把和 place 内容重复的 address 列删掉。
数据 wrangling 不只是“加列”,也包括把冗余信息清理掉,避免后面重复维护同一份内容。
Task 5: 在 Air Crashes 数据上复现完整 wrangling 流程 老师要你把前面学过的流程,自己迁移到一个新数据集上。
读取 AirCrashes.csv
总结数据规模、属性、类型
检查缺失值并决定处理方式
找可以合并的列
删除合并后重复的列
找出有幸存者的事故记录
Step 5.1:读取 Air Crashes 数据 把 Air Crashes 数据读进来,并先看前几行。
Flight
Mode
Casualties
Circumstances
Country
Crew
Date
Ground
Latitude
Location
Longitude
Notes
Passengers
Phase
Reason
Total Dead
Type
截图占位:这里放 aircrash.head() 的截图
Step 5.2:先做基础信息总结 一共有多少条记录
一共有多少列
每列是什么类型
哪些列明显是文本、数值、日期候选列
Step 5.3:检查缺失值并决定怎么处理 你不能看到缺失值就机械 dropna(),要先判断:
缺失是否很多
缺失集中在哪几列
这些列对后续任务是否关键
Step 5.4:给出一种可交的“列合并”做法 只要你的逻辑说得通,并且代码能跑通,就是可以交的。
把 Location 和 Country 合并成一个新的地点字段 Crash Place。
因为地点信息经常分散在多列里,合并后更利于展示和后续分析。
先复制原表,避免改坏原始数据
把地点/国家的空值补成可读占位
再拼成一个新的统一字段
有些 Location 里的值可能本身已经带国家信息,所以这一步属于“可解释的整合做法”,不是唯一答案。
Lab 里这种开放题,关键是你要说明自己的处理逻辑。
截图占位:这里放 Location、 Country、 Crash Place 三列效果截图
Step 5.5:删除合并后冗余的原列 删除已经被整合进 Crash Place 的原始列。
Step 5.6:找出有幸存者的事故记录 然后筛选带有“幸存者”信息、但不是 “No survivors” 的记录:
题目第 5 问明确要求你找“records air crashes with survivors”。
从 notebook 已有样例看, Notes 里出现了:
No survivors
Some survivors
截图占位:这里放 survivors.head() 的截图
Step 5.7:整理成可交的回答草稿
Summary 这周真正学到的,不是某几个零散命令,而是一条很实用的数据整理主线:
先把数据读进来
先看结构,不要急着改
找缺失值,判断问题在哪里
决定是删还是补
按需求创建更方便分析的新列
删除重复信息
把同一套流程迁移到新数据集上
“给你一张陌生表,你能不能把它先看懂,再慢慢整理成更好用的样子。”
这就是 data wrangling 的基础能力。
本周必须理解的知识点
1. DataFrame 是什么 DataFrame 就是一张表,有行、有列、有索引。
2. shape、 columns、 dtypes 为什么总是先看 因为你拿到一个新数据集,第一件事不是“瞎试命令”,而是先搞清:
3. dropna() 和 fillna() 的区别 dropna():删掉含缺失值的行/列
fillna():把缺失值补掉
4. 为什么类别型字段不能乱填 0像颜色、形状、城市名这种字段,更适合填文本占位值。
5. 为什么 Pandas 更推荐向量化操作 因为整列处理通常比 Python 的逐行 for 循环快非常多。
这周的 place vs address 计时对比,就是专门在说明这一点。
关键概念对比
DataFrame vs Series
loc vs iloc
dropna() vs fillna()
向量化操作 vs for 循环
老师可能会问什么
1. 为什么这周一开始总是先看 shape、 columns、 dtypes?
2. 为什么不能对所有缺失值统一填 0?
3. loc 和 iloc 有什么区别?
4. 为什么 for 循环比 Pandas 列操作慢? 因为 Pandas 的向量化操作底层更高效,而 Python 逐行循环开销大。
5. 为什么新增合并列之后还要删原列? 因为 wrangling 的目标之一就是减少重复信息,让表结构更清晰。
import pandas as pd import numpy as np df = pd.DataFrame ([2, 4, 6, 8]) df df.columns.name = " Index " df dates = pd.date_range ( ' 20150125 ' , periods=7 ) dates df = pd.DataFrame ( np.random.randn(7, 5 ) , index= dates, columns= [ ' Adam ' , ' Bob ' , ' Carla ' , ' Dave ' , ' Eve ' ] ) df df2 = pd.DataFrame({ ' A ' : np.random.random_sample(4), # 4 random numbers 'B' : pd.Timestamp( ' 20130102 ' ), # 4 dates, note pandas autofills ' C ' : pd.date_range( ' 20150125 ' ,periods = 4), # 4 dates in a range 'D' : [ ' a ' , ' b ' , ' c ' , ' d ' ], # letters ' E ' : [ " cat " , " dog " , " mouse " , " parrot " ], # text/string ' F ' : ' copy ' }) # note pandas autofills df2 ufo = pd.read_csv ( ' http://bit.ly/uforeports ' ) ufo ufo[[ ' City ' , ' State ' ]][ufo.State == ' NJ ' ] ufo[[ ' City ' , ' State ' ]][ufo.State != ' NJ ' ] ufo.loc[:, ' City ' : ' State ' ].head () from google.colab import drive drive.mount( ' /content/drive ' ) !ls " /content/drive/Shareddrives/FIT5196_S1_2026 " !ls " /content/drive/Shareddrives/FIT5196_S1_2026/Week2 " !ls " /content/drive/Shareddrives/FIT5196_S1_2026/week2 " xmart = pd.read_csv ( ' /content/drive/Shareddrives/FIT5196_S1_2026/Week2/xmart.csv ' , skiprows=1 ) xmart.head() xmart = pd.read_csv ( ' /content/drive/Shareddrives/FIT5196_S1_2026/week2/xmart.csv ' , skiprows=1 ) xmart.head() xmart.describe(include = ' all ' ) ### Task 1 Answer Draft 1.The dataset contains ` ___ ` records and ` ___ ` attributes. 2.The attributes are: ` ___ ` 3.The data type of each attribute is: ` ___ ` 4.Based on the column names and sample records, this dataset appears to contain information about: ` ___ ` ### Task 1 回答草稿 1.该数据集共有 ` ___ ` 条记录、 ` ___ ` 个属性。 2.属性包括: ` ___ ` 3.各属性的数据类型如下: ` ___ ` 4.从字段名称、前几行样例和统计信息来看,这份数据主要记录的是: ` ___ ` ufo[ufo.isna().any(axis= 1 )] ufo1 = ufo.dropna () ufo1.head(20) ufo2 = ufo.fillna (value= 0 ) ufo2.head(20) ufo3 = ufo.copy () ufo3[ ' Colors Reported ' ] = ufo3[ ' Colors Reported ' ].fillna ( ' BLUE ' ) ufo3[10:20] ufo4 = ufo.copy () ufo4[ ' place ' ] = '' ufo4 ufo4[ ' City ' ] = ufo4[ ' City ' ].fillna ( ' No city ' ) ufo4[ ' City ' ] + ' , ' + ufo4[ ' State ' ] ufo4[ ' City ' ].isna().sum() ufo4[ ' place ' ] = ufo4[ ' City ' ] + ' , ' + ufo4[ ' State ' ] ufo4[[ ' City ' , ' State ' , ' place ' ]].head () for i in ufo4.index: ufo4.iloc[i, 6] = ufo4.iloc[i, 0] + ' , ' + ufo4.iloc[i, 3] ufo4[[ ' place ' , ' address ' ]].head () ufo5 = ufo.copy () ufo5[ ' City ' ] = ufo5[ ' City ' ].fillna ( ' No city ' ) ufo5[ ' place ' ] = '' ufo5[ ' address ' ] = '' %%timeit ufo5[ ' place ' ] = ufo5[ ' City ' ] + ' , ' + ufo5[ ' State ' ] %%timeit for i in ufo5.index: ufo5.iloc[i, 6] = ufo5.iloc[i, 0] + ' , ' + ufo5.iloc[i, 3] ufo5.drop(columns =[ ' address ' ], inplace=True ) ufo5.head() !ls " /content/drive/Shareddrives/FIT5196_S1_2026/week2 " aircrash = pd.read_csv ( ' /content/drive/Shareddrives/FIT5196_S1_2026/week2/AirCrashes.csv ' ) aircrash.head() aircrash.columns.tolist() aircrash.describe(include = ' all ' ) aircrash.isna().sum().sort_values(ascending= False ) aircrash[aircrash.isna().any(axis= 1 )].head(20) aircrash2 = aircrash.copy () aircrash2[ ' Location ' ] = aircrash2[ ' Location ' ].fillna ( ' Unknown Location ' ) aircrash2[ ' Country ' ] = aircrash2[ ' Country ' ].fillna ( ' Unknown Country ' ) aircrash2[ ' Crash Place ' ] = aircrash2[ ' Location ' ] + ' | ' + aircrash2[ ' Country ' ] aircrash2[[ ' Location ' , ' Country ' , ' Crash Place ' ]].head () aircrash2.drop(columns =[ ' Location ' , ' Country ' ], inplace=True ) aircrash2.head() aircrash2[ ' Notes ' ].value_counts(dropna =False ).head(20) survivors = aircrash2[ aircrash2[ ' Notes ' ].str.contains( ' survivor ' , case=False, na=False ) & ~aircrash2[ ' Notes ' ].str.contains( ' no survivors ' , case=False, na=False ) ] survivors.head() aircrash3 = aircrash.copy () aircrash3[ ' Onboard ' ] = aircrash3[ ' Crew ' ].fillna (0) + aircrash3[ ' Passengers ' ].fillna (0) survivors_num = aircrash3[aircrash3[ ' Total Dead ' ] < aircrash3[ ' Onboard ' ]] survivors_num.head() ### Task 2 Answer Draft 1.Summary of the dataset The Air Crashes dataset contains ` ___ ` records and ` ___ ` attributes. The main attributes include ` ___ ` . The data types show that the dataset contains both categorical/textual columns and numeric columns. 2.Missing values Yes, the dataset contains missing values, especially in columns such as ` ___ ` . Instead of dropping all incomplete rows directly, I first checked which columns had missing values and then applied suitable treatments depending on the column meaning. 3.Merged columns I merged ` Location ` and ` Country ` into a new column called ` Crash Place ` so that the place information is easier to read and use. 4.Removed duplicated information After creating ` Crash Place ` , I removed the original ` Location ` and ` Country ` columns because their information had already been combined into the new field. 5.Subset with survivors I created a subset of records with survivors by filtering the ` Notes ` column for values that mention survivors but exclude ` No survivors ` .