第 1.2 节 编程练习#
预计学习时长: 40 分钟
练习方式: 建议新建一个 Jupyter Notebook,把下面的数据准备代码抄进去,然后每题独立完成。先写,写不出再展开答案——直接看答案的练习几乎没有效果。
本课程使用的 Pandas 版本是
'3.1.0'
本小节示例代码文件: 。
准备:先把数据建好#
这 5 道题都用同一张订单表。在 Notebook 的第一个单元格执行:
import pandas as pd
data = {
"订单号": [1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008],
"下单日期": ["2024-01-05", "2024-01-08", "2024-01-12", "2024-02-03",
"2024-02-15", "2024-03-02", "2024-03-20", "2024-04-08"],
"城市": ["北京", "上海", "北京", "广州", "上海", "北京", "深圳", "广州"],
"商品": ["手机", "电脑", "耳机", "手机", "键盘", "显示器", "耳机", "手机"],
"销量": [2, 1, 3, 2, 5, 1, 4, 2],
"单价": [3999.0, 7999.0, 599.0, 3999.0, 299.0, 1299.0, 599.0, 3999.0],
"金额": [7998.0, 7999.0, 1797.0, 7998.0, 1495.0, 1299.0, 2396.0, 7998.0],
"客户评分": [4.5, 4.0, 4.8, 3.9, 4.2, 4.6, 4.1, 4.9],
}
df = pd.DataFrame(data)练习 1:从字典创建 DataFrame#
题目: 上面已经建好了 df。现在请你自己动手,用一个新的字典 student_data 创建一个学生信息表,包含 3 列:
姓名:["小明", "小红", "小华"]年龄:[18, 19, 20]城市:["北京", "上海", "广州"]
然后把它存到变量 students,并打印出来。
要求: 不许直接抄上面的 data,自己敲一遍。
点击查看参考答案
student_data = {
"姓名": ["小明", "小红", "小华"],
"年龄": [18, 19, 20],
"城市": ["北京", "上海", "广州"],
}
students = pd.DataFrame(student_data)
print(students)输出:
姓名 年龄 城市
0 小明 18 北京
1 小红 19 上海
2 小华 20 广州要点: 字典的键 = 列名,字典的值 = 这一列的数据(必须是一个列表)。3 个键就是 3 列,值的长度 3 就是 3 行。
练习 2:获取 DataFrame 行和列数#
题目: 用三种方式分别拿到 df 的行数和列数:
用
df.shape一次性拿到;用
len()拿行数;用
df.shape[0]和df.shape[1]分别拿。
把三个结果都 print 出来,对照一下它们是不是一致。
附加要求: 再创建一个只有 0 行 0 列的空表 empty = pd.DataFrame(),打印它的 shape。
点击查看参考答案
# 方式 1:一次性拿到
print(df.shape) # (8, 8)
# 方式 2:len() 拿行数
print(len(df)) # 8
# 方式 3:分别取
print(df.shape[0]) # 8 行数
print(df.shape[1]) # 8 列数
# 空表
empty = pd.DataFrame()
print(empty.shape) # (0, 0)要点: df.shape 返回的是元组,顺序是**(行数,列数),别看反了。len(df) 对 DataFrame 来说返回的是行数**,因为它先问「这张表有几条记录」。
练习 3:指定列创建新 DataFrame#
题目: 已知 df 有 8 列。请完成下面 4 个取列操作,并分别打印出结果的 type:
取出「城市」这一列;
取出「城市」和「商品」两列;
取出「订单号」「城市」「商品」「销量」四列,存到变量
order_info;取出「客户评分」这一列,但要让它保持 DataFrame 类型(提示:想想双层方括号)。
思考题: 为什么第 1 题和第 4 题写的代码看起来只差一层方括号,结果类型却不一样?
点击查看参考答案
# 1. 取一列 → Series
cities = df["城市"]
print(type(cities)) # <class 'pandas.Series'>
# 2. 取两列 → DataFrame
two_cols = df[["城市", "商品"]]
print(type(two_cols)) # <class 'pandas.DataFrame'>
# 3. 取四列
order_info = df[["订单号", "城市", "商品", "销量"]]
print(order_info)
# 4. 单列但保持 DataFrame
scores = df[["客户评分"]]
print(type(scores)) # <class 'pandas.core.frame.DataFrame'>输出(order_info):
订单号 城市 商品 销量
0 1001 北京 手机 2
1 1002 上海 电脑 1
2 1003 北京 耳机 3
3 1004 广州 手机 2
4 1005 上海 键盘 5
5 1006 北京 显示器 1
6 1007 深圳 耳机 4
7 1008 广州 手机 2要点:
df["城市"]→ 单层方括号 → Seriesdf[["城市"]]→ 双层方括号 → DataFrame
内层的 ["城市"] 是一个 Python 列表,Pandas 看到「列表」就理解为「我要这几列」,所以给回一张表;看到「字符串」就理解为「我要这一列」,给回一个 Series。
练习 4:查看各列的数据类型#
题目: 完成下面 4 个操作:
打印整张表每一列的数据类型;
只打印「销量」这一列的类型;
打印「城市」这一列的类型;
打印「客户评分」这一列的类型。
思考题: 第 2、3、4 题的答案分别是什么?为什么「销量」和另外两个不一样?
点击查看参考答案
# 1. 所有列的类型
print(df.dtypes)输出:
订单号 int64
下单日期 str
城市 str
商品 str
销量 int64
单价 float64
金额 float64
客户评分 float64
dtype: object# 2、3、4:单列的类型
print(df["销量"].dtype) # int64
print(df["城市"].dtype) # str
print(df["客户评分"].dtype) # float64要点:
- 「销量」是
int64:因为写的是2、1、3这些整数,全是整数就是 int; - 「客户评分」是
float64:因为写的是4.5、4.0这种带小数点的数; - 「城市」是
str:装的是字符串。
一个小坑 就算你写
4.0而不是4,它还是float64——Python 里4.0就是浮点数。所以想让一列保持整数类型,写的时候不要带小数点。
练习 5:查看数据前 5 行和后 3 行#
题目: 完成下面 4 个操作:
- 查看
df的前 5 行(默认值); - 查看
df的前 3 行; - 查看
df的后 3 行; - 打印「后 3 行」这个结果的行数和列数。
思考题: 第 4 题的结果是多少?如果和你想的不一样,去 df.shape 那里找原因。
点击查看参考答案
# 1. 前 5 行(默认)
df.head()
# 2. 前 3 行
df.head(3)
# 3. 后 3 行
df.tail(3)
# 4. 后 3 行的形状
print(df.tail(3).shape) # (3, 8)df.tail(3) 的输出:
订单号 下单日期 城市 商品 销量 单价 金额 客户评分
5 1006 2024-03-02 北京 显示器 1 1299.0 1299.0 4.6
6 1007 2024-03-20 深圳 耳机 4 599.0 2396.0 4.1
7 1008 2024-04-08 广州 手机 2 3999.0 7998.0 4.9要点: tail(3) 切出来的表是 3 行 8 列——行数被截断了,但列数不变。
对比一下 df.shape 是 (8, 8),你就明白 head/tail 切的是行,不是列。
顺便注意 tail(3) 输出的行索引还是 5、6、7,没有重新从 0 开始编号。这是 Pandas 的一个特性(切片保留原索引),第 2 章讲 reset_index() 时会再碰到它。
加分练习#
做完上面 5 题,如果你还有兴趣,试试这个:
题目: 不看答案,输出一份「数据体检报告」,包含:
- 表的规模(几行几列);
- 每列的类型;
- 数值列的统计摘要(均值、中位数、最大值);
- 前 3 行和后 3 行。
你大概会用到 df.shape、df.dtypes、df.describe()、df.head(3)、df.tail(3)——全是本节学过的方法。
点击查看参考答案
print("=== 规模 ===")
print(df.shape)
print("\n=== 类型 ===")
print(df.dtypes)
print("\n=== 数值摘要 ===")
print(df.describe())
print("\n=== 前 3 行 ===")
print(df.head(3))
print("\n=== 后 3 行 ===")
print(df.tail(3))要点: \n 是换行符,用它把几段输出隔开,报告会好看很多。这是个很实用的小技巧。
练习小结#
| 题号 | 练的是 | 用到的核心方法 |
|---|---|---|
| 1 | 从字典建表 | pd.DataFrame(字典) |
| 2 | 看行数列数 | df.shape、len(df) |
| 3 | 取列 | df["列"](Series)、df[["列1", "列2"]](DataFrame) |
| 4 | 看数据类型 | df.dtypes、df["列"].dtype |
| 5 | 预览数据 | df.head(n)、df.tail(n) |
如果你这 5 题都能独立写出来,第 1 章的核心你已经掌握了。下一节是这一章的 10 个常见问题,把那些「看着眼熟但说不清区别」的地方一次性讲透。