# 4.5.1 读写CSV文件（问答库）

1. 【单选题·易】CSV 的全称和含义是？
   A. Comma-Separated Values，逗号分隔值
   B. Column-Separated Values，列分隔值
   C. Cell-Saved Version，单元格保存版本
   D. Character-Set Values，字符集取值
   **答案：A**
   **解析：** 语料明确：CSV（Comma-Separated Values，逗号分隔值）是一种常见的用于存储表格数据的纯文本格式。

2. 【单选题·易】关于 `to_csv()` 和 `read_csv()` 的调用对象，下列说法正确的是？
   A. 二者都是数据框的成员，都要通过数据框对象调用
   B. `to_csv()` 是数据框的成员，要通过数据框对象调用；`read_csv()` 是pandas的成员，要通过pandas调用
   C. 二者都是pandas的成员，都要写成 `pd.to_csv()`、`pd.read_csv()`
   D. `to_csv()` 是pandas的成员；`read_csv()` 是数据框的成员
   **答案：B**
   **解析：** 语料：`to_csv()` 是数据框的成员，要通过数据框对象调用；`read_csv()` 是pandas的成员，要通过pandas调用。

3. 【判断题·易】`to_csv()` 是数据框的成员，要通过数据框对象调用。
   **答案：√**
   **解析：** 与语料一致。正确写法是 `df.to_csv('renshu.csv', index=True)`，而不是 `pd.to_csv(...)`。

4. 【判断题·易】pandas默认使用UTF-8编码。如果文件是用pandas的 `to_csv` 写的，用 `read_csv` 读取时不用指定编码。
   **答案：√**
   **解析：** 语料原文。由 `to_csv` 写出的文件与 `read_csv` 默认编码一致；其他方式创建的文件则另当别论。

5. 【多选题·中】关于数据框的 `to_csv()`，下列说法正确的有：
   A. 要通过数据框对象调用，例如 `df.to_csv('renshu.csv', index=True)`
   B. `index=True` 指示保存索引，`index=False` 指示不保存索引
   C. 默认用逗号分隔，也可用 `sep` 指定其他分隔符（如 `sep='\t'` 表示制表符）
   D. 它与 `read_csv()` 一样，必须写成 `pd.to_csv(df)`
   **答案：ABC**
   **解析：** A、B、C 均来自 4.5.1 语料。`to_csv()` 是数据框方法，不是 pandas 顶层函数，故 D 错误。

6. 【单选题·中】执行下列代码后，打印出的文件首行（去掉换行）是？

```python
import pandas as pd
from pandas import DataFrame
data = [[800, 750, 500], [700, 800, 600], [680, 720, 580]]
col = ['会计', '保险', '外语']
ind = ['2022', '2023', '2024']
df = DataFrame(data, columns=col, index=ind)
df.to_csv('renshu.csv', index=True)
with open('renshu.csv', encoding='utf-8') as f:
    print(f.readline().strip())
```

   A. `,会计,保险,外语`
   B. `会计,保险,外语`
   C. `2022,800,750,500`
   D. `index,会计,保险,外语`
   **答案：A**
   **解析：** `index=True` 会保存行索引。课程给出的文件首行为 `,会计,保险,外语`：索引列没有列名，故第一个逗号前为空。B 是 `index=False` 的首行；C 是第一行数据，不是表头。

7. 【单选题·中】执行下列代码后，关于 `renshu.csv` 的说法正确的是？

```python
import pandas as pd
from pandas import DataFrame
data = [[800, 750, 500], [700, 800, 600], [680, 720, 580]]
col = ['会计', '保险', '外语']
ind = ['2022', '2023', '2024']
df = DataFrame(data, columns=col, index=ind)
df.to_csv('renshu.csv', index=False)
with open('renshu.csv', encoding='utf-8') as f:
    print(f.read())
```

   A. 首行是 `,会计,保险,外语`，数据行带有 2022、2023、2024
   B. 首行是 `会计,保险,外语`，随后三行为 `800,750,500`、`700,800,600`、`680,720,580`，不保存年份索引
   C. 文件只有表头、没有数据行
   D. 分隔符变成制表符，不再是逗号
   **答案：B**
   **解析：** `index=False` 指示不保存索引。课程给出的文件内容首行为 `会计,保险,外语`，数据行不再出现年份。本题未设置 `sep`，仍用默认逗号。A 是 `index=True` 的情形。

8. 【多选题·中】关于 `pd.read_csv()`，下列说法正确的有：
   A. 它是pandas的成员，通过pandas调用，可以把CSV读取为数据框对象
   B. 如果文件第一列是索引，则应设置参数 `index_col`（如 `index_col=0`），否则不设置
   C. 要根据文件的分隔符设置参数 `sep`
   D. CSV只能用逗号分隔，因此 `read_csv` 不允许使用 `sep` 参数
   **答案：ABC**
   **解析：** A、B、C 是语料对 `read_csv` 的说明。写出也可用 `sep` 指定制表符等其他分隔符，读入必须按同样分隔符设置 `sep`，故 D 错误。

9. 【判断题·中】无论CSV文件是用什么方式创建的，用 `read_csv` 读取时都不必指定编码，因为pandas总能自动识别，不会出现中文乱码。
   **答案：×**
   **解析：** 仅当文件是用pandas的 `to_csv` 写的，读取时才不用指定编码。如果文件是别的方式创建的，读取时需要指定创建时的编码，否则会出现中文乱码。

10. 【单选题·难】执行下列代码后，`df2.shape`、`df2.iloc[0, 0]`、列标签列表分别是？

```python
import pandas as pd
from pandas import DataFrame
data = [[800, 750, 500], [700, 800, 600], [680, 720, 580]]
col = ['会计', '保险', '外语']
ind = ['2022', '2023', '2024']
df = DataFrame(data, columns=col, index=ind)
df.to_csv('renshu.csv', index=True, sep='\t')
df2 = pd.read_csv('renshu.csv', index_col=0, sep='\t')
print(df2.shape)
print(df2.iloc[0, 0])
print(list(df2.columns))
```

    A. `(3, 3)`、`800`、`['会计', '保险', '外语']`
    B. `(3, 4)`、`2022`、多出一列保存下来的年份
    C. `(3, 1)`、整行挤在一列里
    D. `(3, 3)`、`500`、`['会计', '保险', '外语']`
    **答案：A**
    **解析：** 写出用了 `index=True` 与 `sep='\t'`，读入用配对的 `index_col=0` 与 `sep='\t'`，可还原为 3 行 3 列的人数表。`iloc[0, 0]` 是 2022 年会计人数 800，不是外语的 500（那是 `iloc[0, 2]`）。B 是写出保存了索引但读入未设 `index_col` 的典型结果；C 是读入漏写 `sep='\t'`、仍按默认逗号切分的结果。

11. 【简答题·中】请写出完整可运行代码：创建与课程相同的人数数据框（列：会计/保险/外语，行标签：2022/2023/2024），保存为 `renshu.csv` 且保存索引；再用 `read_csv` 读回为数据框并打印。然后说明：`index=True` 与 `index=False` 写出的文件内容有何差别？
    **答案：**

```python
import pandas as pd
from pandas import DataFrame
data = [[800, 750, 500], [700, 800, 600], [680, 720, 580]]
col = ['会计', '保险', '外语']
ind = ['2022', '2023', '2024']
df = DataFrame(data, columns=col, index=ind)
df.to_csv('renshu.csv', index=True)
df2 = pd.read_csv('renshu.csv', index_col=0)
print(df2)
```

    `index=True` 保存索引，文件首行为 `,会计,保险,外语`，数据行带年份（如 `2022,800,750,500`）。`index=False` 不保存索引，首行直接是 `会计,保险,外语`，数据行不再出现年份。读回保存了索引的文件时，应设置 `index_col=0`。
    **解析：** 评分要点：① 用 `DataFrame`/`pd.DataFrame` 按课程数据创建；② `df.to_csv(..., index=True)`；③ `pd.read_csv(..., index_col=0)`；④ 能对比 True/False 时文件是否包含年份索引。写成 `pd.to_csv`、漏 `index_col` 或数据写错可酌情扣分。

12. 【简答题·难】结合下列代码，回答三个问题：（1）为什么必须写成 `df.to_csv(...)` 和 `pd.read_csv(...)`，而不能对调？（2）这里为什么要同时写 `index=True`、`sep='\t'` 与读入的 `index_col=0`、`sep='\t'`？若读入漏掉其中某一个，会出现什么问题？（3）若这个CSV不是用 `to_csv` 写的，而是用其他软件创建且编码不是UTF-8，直接 `read_csv` 可能出现什么现象？应如何处理？

```python
import pandas as pd
from pandas import DataFrame
data = [[800, 750, 500], [700, 800, 600], [680, 720, 580]]
col = ['会计', '保险', '外语']
ind = ['2022', '2023', '2024']
df = DataFrame(data, columns=col, index=ind)
df.to_csv('renshu.csv', index=True, sep='\t')
df2 = pd.read_csv('renshu.csv', index_col=0, sep='\t')
print(df2)
```

    **答案：**
    （1）`to_csv()` 是数据框成员，必须由数据框对象调用；`read_csv()` 是pandas成员，必须由pandas调用。对调后既不符合接口，也无法完成「数据框写出 / 文件读成数据框」。
    （2）写出与读入的参数必须按文件内容配对。本例保存了索引且用制表符分隔，所以读入要设 `index_col=0` 和 `sep='\t'`。漏 `index_col` 时，年份会变成普通列，行标签还原失败；漏 `sep='\t'` 时仍按逗号切分，各列对不齐（往往挤成很少的列）。
    （3）pandas默认UTF-8。其他方式创建的文件若不指定创建时的编码，可能出现中文乱码。处理办法：用 `read_csv` 时指定与文件创建时一致的编码。
    **解析：** 评分要点：① 分清两个函数的调用对象；② 能说明 `index_col` 与 `sep` 要和文件内容配对，并分别说出漏设的后果；③ 能指出非 `to_csv` 文件需指定创建时编码，否则中文乱码。只背函数名、说不清配对关系不得满分。

对应文件：
- `知识库/第4章 pandas数据分析库/4.5.1-读写CSV文件.md`
- `问答库/第4章 pandas数据分析库/4.5.1-读写CSV文件.md`
