# 4.2.2 基于条件的数据筛选（问答库）

1. 【单选题·易】序列和数据框都支持布尔索引。布尔索引的作用是？
   A. 按列标签重命名
   B. 使用布尔值列表或序列，选出对应位置为 True 的元素（数据框中是选出对应的行）
   C. 把数值全部转换成 True/False 后覆盖原数据
   D. 只能删除缺失值
   **答案：B**
   **解析：** 语料：使用一个布尔值列表或序列对象来选择对应位置为 True 的元素，在数据框中是选择对应的行。

2. 【单选题·易】下列关于数据框布尔索引的说法，正确的是？
   A. 布尔索引在数据框中选出的是对应的列
   B. 布尔索引在数据框中选出的是对应的行
   C. 布尔索引只能用于序列，不能用于数据框
   D. 布尔索引必须配合 `loc` 才能使用
   **答案：B**
   **解析：** 课程明确：在数据框中是选择对应的行。序列和数据框都支持布尔索引，语法为 `对象[[True, False,…]]`。

3. 【判断题·易】序列对象进行关系运算后，结果仍是序列对象，且元素值为布尔值。
   **答案：√**
   **解析：** 例如 `close > 20` 得到平安科技 True、南方通信 True、幸福银行 False，dtype 为 bool。

4. 【判断题·易】手写布尔列表做索引时，列表长度可以与序列或数据框的长度不同。
   **答案：×**
   **解析：** 布尔列表（或布尔序列）的长度必须与对象长度一致：序列对应元素个数，数据框对应行数。长度不一致会出错。

5. 【多选题·中】关于布尔索引的语法，下列说法正确的有：
   A. 语法格式为 `对象[[True, False,…]]`
   B. 对象可以是序列对象，也可以是数据框对象
   C. 外层括号中可以是列表，也可以是序列对象，只要其中是布尔值
   D. 布尔索引只能传入 Python 列表，不能传入序列对象
   **答案：ABC**
   **解析：** 课程强调外层括号中可以是列表或序列对象，只要元素是布尔值。D 与语料相反。

6. 【单选题·中】执行下列代码，筛选结果中包含哪些标签？

```python
from pandas import Series
close = Series([44.3, 22.6, 6.5], index=['平安科技', '南方通信', '幸福银行'])
print(close[close > 20])
```

   A. 仅「平安科技」（44.3）
   B. 「平安科技」（44.3）和「南方通信」（22.6）
   C. 「平安科技」「南方通信」「幸福银行」全部保留
   D. 仅「幸福银行」（6.5）
   **答案：B**
   **解析：** `close > 20` 在平安科技、南方通信上为 True，幸福银行 6.5 不满足条件。`close[close > 20]` 把关系运算与布尔索引结合，筛出前两项。

7. 【单选题·中】执行下列代码，结果数据框包含哪些行？

```python
from pandas import DataFrame
data = {'平安科技': [45.2, 47.1, 46.5, 49.8],
        '南方通信': [31.9, 27.3, 25.2, 24.5],
        '幸福银行': [3.4, 4.6, 5.2, 6.8]}
df = DataFrame(data, index=['2024-01', '2024-02', '2024-03', '2024-04'])
print(df[df['平安科技'] > 47])
```

   A. 仅 2024-02（平安科技 47.1）
   B. 2024-02 和 2024-04（平安科技分别为 47.1、49.8）
   C. 2024-01 至 2024-04 全部四行
   D. 仅 2024-04（平安科技 49.8）
   **答案：B**
   **解析：** `df['平安科技'] > 47` 在四个月份上依次为 False、True、False、True，套回数据框后保留 2024-02 与 2024-04 两整行。

8. 【多选题·中】沿用上题中的数据框 `df`，下列哪些写法能选出「平安科技」大于 47 的行？
   A. `df[df['平安科技'] > 47]`
   B. `df[[False, True, False, True]]`
   C. `df['平安科技'] > 47`
   D. `df[df.平安科技 > 47]`
   **答案：ABD**
   **解析：** A 是标准的条件筛选。B 手写布尔列表，True 对应第 2、4 行，结果与 A 相同。D 用属性方式取列后再比较，列名合法时与 A 等价。C 只得到布尔序列，并没有把条件套回数据框，不是筛选后的数据框。

9. 【判断题·中】`df['平安科技'] > 47` 的结果已经是筛选后的数据框，包含满足条件的整行。
   **答案：×**
   **解析：** 数据框选择一列后做关系运算，结果是元素为布尔值的序列，不是数据框。必须写成 `df[df['平安科技'] > 47]`，才能按该条件筛选行。

10. 【单选题·难】执行下列代码，两行 `print` 的输出依次是什么？

```python
from pandas import Series, DataFrame
close = Series([44.3, 22.6, 6.5], index=['平安科技', '南方通信', '幸福银行'])
data = {'平安科技': [45.2, 47.1, 46.5, 49.8],
        '南方通信': [31.9, 27.3, 25.2, 24.5],
        '幸福银行': [3.4, 4.6, 5.2, 6.8]}
df = DataFrame(data, index=['2024-01', '2024-02', '2024-03', '2024-04'])
print(close[[True, False, False]].iloc[0])
print(df[[True, False, True, False]]['幸福银行'].iloc[1])
```

   A. 44.3 和 5.2
   B. 22.6 和 3.4
   C. 44.3 和 3.4
   D. 6.5 和 5.2
   **答案：A**
   **解析：** `close[[True, False, False]]` 只保留第一项平安科技 44.3。`df[[True, False, True, False]]` 保留第 1、3 行（2024-01 与 2024-03）；再取「幸福银行」列后，`.iloc[1]` 是筛选结果中的第 2 行，即 2024-03 的 5.2。

11. 【简答题·中】请写出完整可运行代码：创建与课程相同的收盘价序列 `close` 和股价数据框 `df`，然后（1）筛出收盘价大于 20 的股票；（2）筛出「平安科技」股价高于 47 的月份。
   **答案：**

```python
from pandas import Series, DataFrame
close = Series([44.3, 22.6, 6.5], index=['平安科技', '南方通信', '幸福银行'])
data = {'平安科技': [45.2, 47.1, 46.5, 49.8],
        '南方通信': [31.9, 27.3, 25.2, 24.5],
        '幸福银行': [3.4, 4.6, 5.2, 6.8]}
df = DataFrame(data, index=['2024-01', '2024-02', '2024-03', '2024-04'])
print(close[close > 20])          # 平安科技 44.3，南方通信 22.6
print(df[df['平安科技'] > 47])     # 2024-02 与 2024-04 两行
```

   **解析：** 评分要点：① `close` 用三个收盘价和对应股票标签创建；② `df` 用字典加月份行标签创建；③ 序列筛选写成 `close[close > 20]`；④ 数据框筛选写成 `df[df['平安科技'] > 47]`。四步正确给满分。

12. 【简答题·难】结合下列代码，回答三个问题：（1）`close > 20` 与 `close[close > 20]` 的结果类型和含义有何不同？（2）为什么 `df['平安科技'] > 47` 不能直接当作「筛出来的月份数据」？正确写法是什么？（3）`df[[True, False, True, False]]` 与 `df[df['平安科技'] > 47]` 选出的行是否相同？请说明理由。

```python
from pandas import Series, DataFrame
close = Series([44.3, 22.6, 6.5], index=['平安科技', '南方通信', '幸福银行'])
data = {'平安科技': [45.2, 47.1, 46.5, 49.8],
        '南方通信': [31.9, 27.3, 25.2, 24.5],
        '幸福银行': [3.4, 4.6, 5.2, 6.8]}
df = DataFrame(data, index=['2024-01', '2024-02', '2024-03', '2024-04'])
print(close > 20)
print(close[close > 20])
print(df['平安科技'] > 47)
print(df[df['平安科技'] > 47])
print(df[[True, False, True, False]])
```

   **答案：**
   （1）`close > 20` 是关系运算，结果是布尔序列（True、True、False）；`close[close > 20]` 把该布尔序列当作索引，结果是筛选后的数值序列（平安科技 44.3、南方通信 22.6）。
   （2）`df['平安科技'] > 47` 只是一列上的布尔序列（False、True、False、True），不含各列股价。正确写法是 `df[df['平安科技'] > 47]`，才能按行筛出 2024-02 与 2024-04 的整行。
   （3）不同。前者按位置保留第 1、3 行（2024-01、2024-03）；后者按「平安科技 > 47」保留 2024-02、2024-04。手写布尔列表与条件运算得到的 True 位置不必相同。
   **解析：** 评分要点：① 分清「布尔序列」与「用布尔序列做筛选」；② 指出列上的关系运算不是数据框；③ 对比位置布尔列表与条件筛选选出的行不同。三点答全给满分。

---

文件路径：
- 知识库：`知识库/第4章 pandas数据分析库/4.2.2-基于条件的数据筛选.md`（正文约 475 字）
- 问答库：`问答库/第4章 pandas数据分析库/4.2.2-基于条件的数据筛选.md`（12 题：易 4 / 中 6 / 难 2；含单选、多选、判断、简答；涉及数据的题目均带可运行代码）
