Pandas read_csv() Python 与例子
⚡ 智能摘要
Pandas 的 read_csv() 函数只需一次调用即可将逗号分隔的本地或远程文件转换为 DataFrame。本教程将导入 UCI 成人人口普查数据集,为其十五列命名,并使用 groupby 聚合函数汇总结果。
在 Pandas 中导入 CSV
在 TensorFlow 教程中,您将使用 成人数据集它常用于分类任务。下面使用的文件是原始数据。 adult.data 可以从 UCI 机器学习库导出数据集,数据集页面也提供压缩包下载。 ucimlrepo 如果直接路径无法解析,则打包。
数据以 CSV 格式存储。该数据集包含 8 个分类变量:
- 工人阶级
- 教育
- 婚姻
- 占用
- 关系
- 种族
- 性别
- 祖国
以及 6 个连续变量:
- 年龄
- 风车
- 教育编号
- 资本收益
- 资本损失
- hours_week
连同收入 label 列,这将构成你要传递给的 15 个列名。 熊猫 在下一节。
Pandas read_csv() 方法
要导入 CSV 数据集,可以使用 `pd.read_csv()` 对象。其基本签名如下:
Pandas read_csv() 语法
pandas.read_csv(filepath_or_buffer, sep=',', names=None, index_col=None, skipinitialspace=False)
- 文件路径或缓冲区: 小路, URL或者,保存数据的类文件对象
- 分隔符=','要使用的分隔符
- 名称=无:为列命名。如果数据集有十列,则需要提供十个列名。
- index_col=无:要用作行索引的列。传递 False 可强制使用新的整数索引。
- skipinitialspace=False:跳过分隔符后的空格
完整的论点列表请查看官方文件。 pandas.read_csv() 文档.
Pandas read_csv() 示例
下面的代码片段列出了所有 15 列,指向 UCI 文件,并删除了此特定数据集中每个逗号后面的空格。
## Import csv import pandas as pd ## Define path data COLUMNS = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country', 'label'] PATH = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data" df_train = pd.read_csv(PATH, skipinitialspace=True, names = COLUMNS, index_col=False) df_train.shape
输出:
(32561, 15)
该形状确认有 32,561 行和 15 列,因此 COLUMNS 中的每个名称都与文件中的一个字段匹配。
Pandas read_csv() 函数的关键参数
`read_csv()` 函数接受超过五十个参数,但其中一小部分几乎涵盖了所有实际导入操作。以下列出的默认值均来自最新的 pandas API 文档。
| 参数 | 默认 | 它做什么 |
| 九月 | '' | 用作分隔符的字符或正则表达式。对于其他格式,请使用 sep=';' 或 sep='\t'。 |
| 头 | '推断' | 包含列标签的行号。如果文件没有标题行,则传递 header=None。 |
| 名称 | 没有设置 | 列标签的显式列表。与 header=0 结合使用可替换现有标题。 |
| index_col | 没有 | 用作行索引的列。index_col=False 强制使用普通整数索引。 |
| 使用列 | 没有 | 按标签或位置加载列子集。这样可以减少解析时间和内存占用。 |
| 数据类型 | 没有 | 列数据类型,例如 {'age': 'int32'}。跳过类型推断。 |
| na_values | 没有 | 需要读取为 NaN 的额外字符串,例如成人数据集中的“?”占位符。 |
| 跳过行数 / 行数 | 没有 | 跳过前几行,或者只读取前 N 行数据。 |
| 解析日期 | 没有 | 读取时要转换为日期时间的列,与 date_format 配对。 |
| 编码 | 'utf-8' | 文件文本编码。对于旧版导出文件,请使用“latin-1”或“cp1252”。 |
| 块大小 | 没有 | 返回一个迭代器,该迭代器以 N 行为单位生成文件块。 |
| on_bad_lines | '错误' | 如何处理格式错误的行:引发错误、发出警告或跳过它们。 |
其中两点值得特别说明。 index_col=False 这与不设置该值不同:它明确地告诉 Pandas 不要提升第一列,这正是当文件每行都以一个多余的分隔符结尾时所需要的。 names 会静默覆盖文件中声明的任何内容,所以请忽略。 header=0 当 CSV 文件确实包含标题行时,它会显示出来。
Pandas groupby() 方法
查看数据的简便方法是使用 groupby 方法。此方法可以帮助您按组汇总数据。以下是 groupby() 方法可用的聚合列表:
- 计数:计数
- 分钟: 分钟
- 最大:最大
- 平均值:平均值
- 中位数:中位数
- 标准差:std
- 和别的
在 groupby() 函数内部,你需要在应用聚合之前指定要分组的列。
让我们来看一个单独的组ping 使用成人数据集,您将获得所有连续变量按收入类型(高于 50 万美元或低于 50 万美元)划分的平均值:
df_train.groupby(['label']).mean()
| 标签 | 年龄 | 风车 | 教育编号 | 资本收益 | 资本损失 | hours_week |
| <= 50K | 36.783738 | 190340.86517 | 9.595065 | 148.752468 | 53.142921 | 38.840210 |
| > 50K | 44.249841 | 188005.00000 | 11.611657 | 4006.142456 | 195.001530 | 45.473026 |
您可以根据家庭类型获取最低年龄要求:
df_train.groupby(['label'])['age'].min() label <=50K 17 >50K 19 Name: age, dtype: int64
您还可以按多个列进行分组。例如,您可以根据家庭类型和婚姻状况获得最大资本收益。
df_train.groupby(['label', 'marital'])['capital_gain'].max() label marital <=50K Divorced 34095 Married-AF-spouse 2653 Married-civ-spouse 41310 Married-spouse-absent 6849 Never-married 34095 Separated 7443 Widowed 6849 >50K Divorced 99999 Married-AF-spouse 7298 Married-civ-spouse 99999 Married-spouse-absent 99999 Never-married 99999 Separated 99999 Widowed 99999 Name: capital_gain, dtype: int64
在进行分组后,您可以创建图表。一种方法是直接绘制分组结果。
为了生成更清晰的图表,请在调用 mean() 函数后使用 unstack() 函数,这样婚姻状况就会从索引移到列中。图表随后会分成两组,分别对应不同的收入标签,而不是像扁平的多级索引那样生成十四个(2*7)柱状图。
如果使用 Jupyter 笔记本请记住添加 %matplotlib inline,否则将不会显示任何图表。
%matplotlib inline df_plot = df_train.groupby(['label', 'marital'])['capital_gain'].mean().unstack() df_plot
将该未堆叠的帧绘制成柱状图,得到下图。
如何使用 Pandas 读取大型 CSV 文件
成年数据集虽然很小,但同样的调用却可能导致导出几GB的数据时卡住。三个参数就能完成大部分工作。
- 使用列 仅加载实际需要的列。pandas 文档指出,这可以显著加快解析速度并降低内存占用。
- 数据类型 将每一列固定为一个类型,因此 Pandas 会跳过类型推断,并且默认情况下不会将整数扩展为 64 位。
- 块大小 返回的是 TextFileReader 而不是 DataFrame,这样你就可以遍历 N 行的数据块并进行聚合。
import pandas as pd # read only the columns you need, with explicit types cols = ['age', 'education', 'capital_gain', 'label'] types = {'age': 'int32', 'capital_gain': 'int32'} df = pd.read_csv(PATH, names=COLUMNS, usecols=cols, dtype=types, skipinitialspace=True, index_col=False) # stream the file in fixed-size chunks instead of loading it whole total = 0 for chunk in pd.read_csv(PATH, names=COLUMNS, chunksize=10000, skipinitialspace=True, index_col=False): total = total + len(chunk) print(total)
基本条件具备后,还有两种选择会有所帮助。 engine='pyarrow' 切换到多线程 Arrow 解析器,并且 dtype_backend='pyarrow' 将结果保存在带箭头的列中。 low_memory 默认值为 True,它会在内部分段解析文件,但可能会在一列中产生混合类型;请显式设置 dtype,而不是依赖于它。
最后, compression='infer' 这意味着以 .gz、.zip、.bz2、.xz 或 .zst 结尾的路径会被即时解压缩,因此无需在读取之前解压归档文件。
常见的 Pandas read_csv() 错误及其解决方法
read_csv() 函数的失败大多由以下四个原因造成,每个原因都有一个记录在案的参数可以解决。
| 误差 | 原因 | 固定 |
| 文件未找到错误 | 路径是相对于工作目录的,而不是相对于脚本的。 | 使用绝对路径,或确认 URL 协议可以是 http、ftp、s3、gs 或 file 之一。 |
| Unicode解码错误 | 该文件不是 UTF-8 编码,而 UTF-8 是默认编码。 | 请传递 encoding='latin-1' 或正确的编解码器,或者 encoding_errors='replace'。 |
| 解析错误:数据标记化错误 | 一行数据包含的字段比表头声明的字段多。 | 传递 on_bad_lines='skip' 或 'warn',或设置正确的分隔符。 |
| 数据类型警告:列包含混合类型 | 分块类型推断在同一列中发现了不同的类型。 | 指定显式数据类型,或者设置 low_memory=False。 |
| 列偏移了一位 | 尾随分隔符会使 Pandas 将第一个字段提升到索引级别。 | 传递 index_col=False。 |
成人数据集直接显示了缺失值的情况:未知的工作类别、职业和本地国家条目存储为字面问号,因此除非您声明它们,否则它们将以字符串“?”的形式出现。
# tolerate rows with too many fields instead of raising df = pd.read_csv(PATH, names=COLUMNS, on_bad_lines='skip') # read a file that is not UTF-8 df = pd.read_csv('sales.csv', encoding='latin-1') # treat the dataset's '?' placeholder as a missing value df = pd.read_csv(PATH, names=COLUMNS, na_values='?', skipinitialspace=True)

