# 4.2.1 使用选择器和快速访问器（问答库）

1. 【单选题·易】按行访问数据框时，选择器 `loc` 与 `iloc` 的分工是？
   A. `loc` 通过整数索引访问，`iloc` 通过标签访问
   B. `loc` 通过标签访问，`iloc` 通过整数索引访问
   C. 二者完全等价，可以互换
   D. `loc` 只能取单列，`iloc` 只能取单行
   **答案：B**
   **解析：** 课程表4-1：`loc` 通过标签进行数据访问，`iloc` 通过整数索引进行数据访问。

2. 【单选题·易】按列访问数据框时，下列哪种写法把列标签当作字符串处理，因而可以处理任意字符的列标签？
   A. `对象名.列标签`
   B. `对象名['列标签']`
   C. `对象名.loc['列标签']`
   D. `对象名.at['列标签']`
   **答案：B**
   **解析：** `对象名['列标签']` 必须加引号，列标签作为字符串，可处理任意字符。点号写法 `对象名.列标签` 对列名限制更严。

3. 【判断题·易】数据框按列访问不支持切片，但可以用列标签列表一次选取多列。
   **答案：√**
   **解析：** 课程明确：按列访问不支持切片，但支持索引标签列表，语法为 `对象名[['列标签',…]]`，例如 `df[['平安科技', '幸福银行']]`。

4. 【判断题·易】使用 `loc` 按行标签对数据框切片时，切片结果包含结束标签。
   **答案：√**
   **解析：** 例如 `df.loc['2024-01':'2024-02']` 会同时包含 2024-01 和 2024-02。对比：`df.iloc[0:2]` 按整数位置切片，不含结束位置。

5. 【多选题·中】使用 `对象名.列标签`（属性方式）访问列时，列标签必须满足哪些要求？
   A. 不能有空格
   B. 不能有特殊字符
   C. 不能与已有的方法或属性重名
   D. 必须是默认的整数列名
   **答案：ABC**
   **解析：** 点号访问对列标签要求较严：不能有空格、特殊字符，且不能与已有方法或属性重名。任意字符的列名应改用 `对象名['列标签']`。D 无此要求。

6. 【单选题·中】执行下列代码，输出是什么？

```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["平安科技"]['2024-02'])
```

   A. 45.2
   B. 47.1
   C. 4.6
   D. 31.9
   **答案：B**
   **解析：** 先按列再取元素时，列标签在前、行标签在后。平安科技在 2024-02 的值为 47.1。

7. 【单选题·中】沿用上题中的数据框 `df`（列顺序为平安科技、南方通信、幸福银行），`df.iloc[1, 2]` 的值是？
   A. 47.1
   B. 27.3
   C. 4.6
   D. 5.2
   **答案：C**
   **解析：** 行索引 1 对应 2024-02，列索引 2 对应幸福银行，交叉处为 4.6。注意 `iloc` 用整数位置，不是标签。

8. 【多选题·中】关于快速访问器 `at[]` 和 `iat[]`，下列说法正确的有：
   A. 只用于访问单个元素
   B. 功能与 `loc`、`iloc` 类似，但性能得到优化、速度更快
   C. `at[]` 通过行和列的标签获取元素
   D. `iat[]` 同样通过行和列的标签获取元素
   **答案：ABC**
   **解析：** `iat[]` 通过整数位置访问单个元素，不是通过标签。行在前、列在后：`df.at['2024-02','平安科技']` 为 47.1，`df.iat[0, 2]` 为 3.4。

9. 【判断题·中】`df.at['2024-02', '平安科技']` 与 `df.iat[0, 2]` 都是先行后列：前者用标签，后者用整数位置。
   **答案：√**
   **解析：** 课程强调 `at[]`「行标签在前，列标签在后」，`iat[]`「行索引在前，列索引在后」。`iat[0, 2]` 对应 2024-01 的幸福银行，值为 3.4。

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.iloc[0:2, 0:2])
```

   A. 前 2 行、前 2 列交叉处：2024-01 与 2024-02 的平安科技、南方通信
   B. 前 2 行的全部 3 列（含幸福银行）
   C. 前 3 行、前 3 列（`iloc` 切片包含结束位置）
   D. 仅 2024-01 的平安科技一个元素
   **答案：A**
   **解析：** `df.iloc[0:2, 0:2]` 切前 2 行和前 2 列交叉处的数据块。`iloc` 不含结束位置，故不含第 3 行、第 3 列。仅按列切片应写 `df.iloc[:, 0:2]`。

11. 【简答题·中】请写出完整可运行代码：创建与课程相同的股价数据框 `df`，然后（1）用属性方式取出「南方通信」列；（2）用 `loc` 取出 2024-01 行中「平安科技」的值。
   **答案：**

```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.南方通信)
print(df.loc['2024-01']['平安科技'])  # 输出 45.2
```

   **解析：** 评分要点：① 用字典加 `index` 创建数据框，行标签为四个月份；② `df.南方通信` 为属性访问列（列名无空格、无特殊字符）；③ `loc` 取行后再取列，行标签在前、列标签在后，结果为 45.2。写成 `df.loc['2024-01', '平安科技']` 亦可酌情给分。

12. 【简答题·难】结合下列代码，回答三个问题：（1）`df['平安科技']['2024-02']` 与 `df.loc['2024-01']['平安科技']` 在「行列先后顺序」上有何不同？（2）`df.loc['2024-01':'2024-02']` 与 `df.iloc[0:2]` 的切片范围是否等价？结束位置是否包含？（3）若只要一个元素且追求速度，应选用哪对访问器？各写一条对应语句取出 2024-02 的平安科技、以及第 1 行第 3 列（幸福银行、2024-01）。

```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['平安科技']['2024-02'])
print(df.loc['2024-01']['平安科技'])
print(df.loc['2024-01':'2024-02'])
print(df.iloc[0:2])
print(df.at['2024-02', '平安科技'])
print(df.iat[0, 2])
```

   **答案：**
   （1）按列再取元素是列标签在前、行标签在后；`loc` 按行再取元素是行标签在前、列标签在后。前者输出 47.1，后者输出 45.2。
   （2）对本例数据二者行范围等价，都得到 2024-01 与 2024-02。但规则不同：`loc` 标签切片包含结束标签，`iloc` 整数切片不含结束位置。
   （3）用快速访问器 `at[]`、`iat[]`（只取单个元素，比 `loc`/`iloc` 更快）。`df.at['2024-02', '平安科技']` 为 47.1；`df.iat[0, 2]` 为 3.4。
   **解析：** 评分要点：① 分清按列链式与 `loc` 链式的行列顺序；② 说清 `loc` 闭区间、`iloc` 半开区间；③ 点明 `at`/`iat` 只取单元素且先行后列，两条语句与结果正确。三点答全给满分。
