# 4.2.3 多条件联合筛选（问答库）

1. 【单选题·易】当筛选条件多于一个时，课程用来组合条件、形成多条件联合筛选的逻辑运算符是？
   A. Python 的 `and`、`or`
   B. `&`（与）、`|`（或）
   C. `+`、`-`
   D. `&&`、`||`
   **答案：B**
   **解析：** 语料明确：条件多于一个时，通过逻辑运算符 `&`（与）、`|`（或）进行组合。不能用 Python 的 `and`/`or`，也不是 C 语言风格的 `&&`/`||`。

2. 【单选题·易】在多条件联合筛选中，`&` 与 `|` 的含义分别是？
   A. `&` 表示或，`|` 表示与
   B. `&` 表示与，`|` 表示或
   C. 二者都表示与
   D. 二者都表示或
   **答案：B**
   **解析：** `&` 是与运算，要求各条件同时为 True；`|` 是或运算，只要有一个条件为 True 即可。

3. 【判断题·易】多条件联合筛选时，每个条件都要用圆括号括起来。
   **答案：√**
   **解析：** 课程示例 `close[(close>20) & (close<40)]` 的注释写明「每个条件都要用圆括号」。漏掉括号时 `&`、`|` 会先于比较运算结合，容易报错。

4. 【判断题·易】可以把 Python 的 `and`、`or` 直接写成 `close[close>20 and close<40]` 来做多条件筛选。
   **答案：×**
   **解析：** 序列上的多条件必须用 `&`、`|` 做逐元素逻辑运算。`and`/`or` 只能处理标量真值，对序列会报真值含糊类错误。正确写法是 `close[(close>20) & (close<40)]`。

5. 【多选题·中】下列哪些写法符合课程中的多条件联合筛选？
   A. `close[(close>20) & (close<40)]`
   B. `close[close>20 & close<40]`
   C. `df[(df['平安科技'] > 47) & (df['南方通信']>26)]`
   D. `df[df['平安科技'] > 47 and df['南方通信']>26]`
   **答案：AC**
   **解析：** A、C 与课程示例一致，每个条件都加了圆括号并用 `&` 连接。B 漏了括号；D 误用了 `and`。

6. 【单选题·中】执行下列代码，输出的标签和值是？

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

   A. 平安科技    44.3
   B. 南方通信    22.6
   C. 幸福银行     6.5
   D. 空序列（没有任何元素）
   **答案：B**
   **解析：** 需同时大于 20 且小于 40。44.3 不小于 40，6.5 不大于 20，只有南方通信 22.6 满足，与课程输出一致。

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) & (df['南方通信'] > 26)])
```

   A. 仅 2024-01（南方通信 31.9 最大）
   B. 仅 2024-02（平安科技 47.1，南方通信 27.3）
   C. 2024-02 与 2024-04（平安科技都大于 47）
   D. 全部四行
   **答案：B**
   **解析：** `&` 要求两列条件同时成立。2024-02：47.1>47 且 27.3>26。2024-04 的平安科技 49.8>47，但南方通信 24.5 不大于 26，整行被去掉。结果与课程一致，幸福银行 4.6 随该行保留。

8. 【多选题·中】沿用上题数据框 `df`，执行 `df[(df['平安科技'] > 47) | (df['南方通信'] > 26)]` 后，结果中会出现哪些行标签？
   A. 2024-01
   B. 2024-02
   C. 2024-03
   D. 2024-04
   **答案：ABD**
   **解析：** `|` 是或：任一条件为 True 即保留。2024-01 南方通信 31.9>26；2024-02 两条件都真；2024-04 平安科技 49.8>47。2024-03 的 46.5 不大于 47、25.2 不大于 26，被排除。

9. 【判断题·中】对数据框做多条件联合筛选时，组合后的布尔序列用作行索引，结果仍是数据框，列结构不变。
   **答案：√**
   **解析：** 课程中 `df[(df['平安科技'] > 47) & (df['南方通信']>26)]` 选出满足条件的行，三列（平安科技、南方通信、幸福银行）都还在，只是行数变少。

10. 【单选题·难】执行下列代码，结果数据框的行标签是？

```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['平安科技'] > 46) & (df['南方通信'] < 28) & (df['幸福银行'] > 5)].index.tolist())
```

   A. `['2024-01', '2024-02']`
   B. `['2024-02']`
   C. `['2024-03', '2024-04']`
   D. `['2024-02', '2024-03', '2024-04']`
   **答案：C**
   **解析：** 三个条件必须同时成立。2024-01：45.2 不大于 46。2024-02：幸福银行 4.6 不大于 5。2024-03：46.5>46、25.2<28、5.2>5。2024-04：49.8>46、24.5<28、6.8>5。故为 2024-03 与 2024-04。三个条件同样都要加圆括号。

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

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

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) & (df['南方通信'] > 26)])  # 仅 2024-02
```

   **解析：** 评分要点：① 用 `Series`/`DataFrame` 按课程数据创建对象；② 两个条件都加圆括号并用 `&` 连接；③ 序列结果为南方通信 22.6，数据框仅保留 2024-02 一行。漏括号或改用 `and` 不得满分。

12. 【简答题·难】结合下列代码回答：（1）`&` 筛选后留下哪一行、三列取值各是多少？（2）若把 `&` 改成 `|`，会多留下哪些行？请说明各行是靠哪一列条件入选的。（3）为什么每个条件都要加圆括号？能否把 `&` 换成 `and`？

```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) & (df['南方通信'] > 26)])
print(df[(df['平安科技'] > 47) | (df['南方通信'] > 26)])
```

   **答案：**
   （1）只留 2024-02：平安科技 47.1，南方通信 27.3，幸福银行 4.6。
   （2）改成 `|` 后共三行：原 2024-02 仍在；多留下 2024-01（南方通信 31.9>26）和 2024-04（平安科技 49.8>47）。2024-03 两条件都假，仍被排除。
   （3）必须加圆括号，否则 `&`、`|` 会先于比较运算结合，引发类型错误或错误结果。不能换成 `and`：`and` 不能对序列逐元素运算。
   **解析：** 评分要点：① `&` 结果与课程示例一致，三列数值正确；② 能区分与/或，指出 2024-01、2024-04 各自命中的条件；③ 说明括号是硬性要求，并否定 `and`。三点答全给满分。
