Python 0基础练习 数据分析 2
在数据分析流程中,“数据加载” 是第一步 —— 只有把 Excel/CSV 里的原始数据导入到 Python 中,才能进行后续的清洗、分析和可视化。而 pandas 作为 Python 数据分析的 “瑞士军刀”,提供了极简的 API 来读取 Excel/CSV 文件,同时自带强大的 “数据初探” 工具,能帮你快速摸清数据的 “底细”(比如有多少行多少列、数据类型是什么、有没有缺失值)。
今天这篇教程,从零基础视角出发,分 3 大模块讲解:环境准备→读取 Excel/CSV(含踩坑指南)→数据基本信息查看(实战技巧),所有代码可直接复制运行,帮你轻松迈过数据分析的第一道坎。
一、先做准备:安装 pandas 及依赖库
pandas 本身不自带读取 Excel 的能力,需要额外安装依赖库;读取 CSV 则无需额外依赖。先确保你的环境里有这些库,新手直接用pip安装即可:
1. 安装核心库(一行命令)
打开终端(Windows 用 cmd,Mac 用终端),输入以下命令:
|
# 安装pandas(核心)+ openpyxl(读取Excel 2007+格式.xlsx)+ xlrd(读取旧版Excel .xls格式) pip install pandas openpyxl xlrd |
2. 依赖库说明(避免踩坑)
- pandas:核心库,负责数据加载和处理;
- openpyxl:必须装!用于读取.xlsx格式的 Excel 文件(2007 及以后版本,现在主流格式);
- xlrd:用于读取.xls格式的旧版 Excel 文件(如果你的数据是.xls,才需要装;新版 xlrd 默认不支持.xlsx,所以必须配合 openpyxl)。
安装完成后,在 Python 中导入 pandas(惯例简写为pd):
|
import pandas as pd # 导入pandas,简写为pd(行业通用) |
二、读取 CSV 文件:最常用的文本数据格式
CSV(逗号分隔值)是数据分析中最常用的格式 —— 体积小、兼容性强,几乎所有工具(Excel、Python、R)都能处理。pandas 用pd.read_csv()读取,基础用法超简单,重点解决 “中文乱码”“指定列读取” 等新手常见问题。
1. 基础读取:1 行代码加载 CSV
假设有一个销售数据.csv文件,内容如下(存放在代码同一目录下,路径最简单):
|
日期 |
产品类别 |
销售额 |
销量 |
地区 |
|
2024-01-01 |
家电 |
5200 |
26 |
华北 |
|
2024-01-02 |
服装 |
3800 |
95 |
华东 |
|
2024-01-03 |
家电 |
6500 |
32 |
华南 |
|
2024-01-04 |
食品 |
1200 |
240 |
华北 |
读取代码:
|
# 读取CSV文件(文件和代码同一目录,直接写文件名) df = pd.read_csv("销售数据.csv") # df是DataFrame,pandas的核心数据结构(类似Excel表格) # 打印数据类型,确认读取成功 print("数据类型:", type(df)) # 输出:数据类型: <class 'pandas.core.frame.DataFrame'> |
- 关键概念:DataFrame(简称 “df”)是 pandas 的 “表格型数据结构”,对应 Excel 的 “工作表”—— 有行索引(左侧数字)、列名(顶部标题),每个单元格有对应的值,是后续所有分析的基础。
2. 解决新手第一坑:中文乱码(encoding 参数)
如果 CSV 文件包含中文,直接读取可能出现乱码(比如 “华北” 变成 “北区”),这是因为文件编码格式和 pandas 默认编码(utf-8)不匹配。
常见编码及解决方案:
|
乱码原因 |
编码参数 |
适用场景 |
|
文件是 GBK 编码(Windows 保存的 CSV 常这样) |
encoding="gbk" |
中文 Windows 系统保存的 CSV |
|
文件是 UTF-8 编码(Mac/Linux 常用) |
encoding="utf-8" |
默认值,大部分情况适用 |
|
UTF-8 编码但带 BOM(少见) |
encoding="utf-8-sig" |
解决 “utf-8 编码仍乱码” 问题 |
代码示例(解决 GBK 编码乱码):
|
# 如果读取时中文乱码,加encoding="gbk" df = pd.read_csv("销售数据.csv", encoding="gbk") |
- 怎么判断编码?:如果不确定文件编码,先试utf-8,乱码再试gbk,90% 的中文 CSV 问题都能解决。
3. 实用参数:按需求读取(不是所有数据都要加载)
实际工作中,CSV 文件可能有几十列、几万行,我们往往只需要其中几列 —— 用read_csv()的参数筛选,避免加载无用数据,提升效率。
常用参数及案例:
|
参数名 |
作用 |
示例代码 |
效果 |
|
usecols |
指定要读取的列(列名或索引) |
pd.read_csv("销售数据.csv", usecols=["日期", "销售额", "地区"]) |
只读取 “日期、销售额、地区”3 列 |
|
index_col |
指定某列为 “行索引”(代替默认数字) |
pd.read_csv("销售数据.csv", index_col="日期") |
用 “日期” 列作为行索引(左侧不再是 0,1,2) |
|
skiprows |
跳过前 N 行(比如跳过标题上方的注释) |
pd.read_csv("销售数据.csv", skiprows=1) |
跳过第 1 行,从第 2 行开始读(如果第 1 行是注释) |
|
nrows |
只读取前 N 行(快速预览大文件) |
pd.read_csv("销售数据.csv", nrows=100) |
只读取前 100 行(适合 GB 级大文件,避免卡死) |
案例:读取指定列 + 用日期做行索引
|
# 只读取“日期、产品类别、销售额”3列,并用“日期”做行索引 df = pd.read_csv( "销售数据.csv", usecols=["日期", "产品类别", "销售额"], # 指定列 index_col="日期" # 行索引 ) print(df.head()) # 打印前5行(后续会讲head()) # 输出(行索引变成日期): # 产品类别 销售额 # 日期 # 2024-01-01 家电 5200 # 2024-01-02 服装 3800 # 2024-01-03 家电 6500 # 2024-01-04 食品 1200 |
三、读取 Excel 文件:支持多工作表、复杂格式
Excel 比 CSV 更复杂(支持多工作表、合并单元格、公式),pandas 用pd.read_excel()读取,核心解决 “指定工作表”“处理合并单元格” 等问题。
1. 基础读取:读取 Excel 默认工作表
假设有一个销售数据.xlsx文件,包含 2 个工作表:“1 月销售”(默认工作表,即打开 Excel 显示的第一个表)和 “2 月销售”,先读取默认工作表:
|
# 读取Excel默认工作表(需要指定engine="openpyxl",否则可能报错) df = pd.read_excel("销售数据.xlsx", engine="openpyxl") # engine必须加,确保读取.xlsx print("默认工作表数据:") print(df.head()) |
- 为什么加engine="openpyxl"?:pandas 默认可能调用xlrd读取 Excel,但新版xlrd不支持.xlsx格式,所以必须明确指定用openpyxl引擎(对应我们之前装的库)。如果是旧版.xls文件,引擎用engine="xlrd"。
2. 指定工作表读取(sheet_name 参数)
这是读取 Excel 最常用的需求 —— 比如只读取 “2 月销售” 工作表,有 3 种指定方式:
|
指定方式 |
示例代码 |
说明 |
|
工作表名称(推荐) |
pd.read_excel("销售数据.xlsx", engine="openpyxl", sheet_name="2月销售") |
直接写工作表名,清晰不易错 |
|
工作表索引(从 0 开始) |
pd.read_excel("销售数据.xlsx", engine="openpyxl", sheet_name=1) |
0 是第一个表,1 是第二个表(适合表名复杂时) |
|
读取多个工作表 |
pd.read_excel("销售数据.xlsx", engine="openpyxl", sheet_name=["1月销售", "2月销售"]) |
返回字典,key 是表名,value 是 DataFrame |
案例 1:读取指定名称的工作表
|
# 读取“2月销售”工作表 df_feb = pd.read_excel( "销售数据.xlsx", engine="openpyxl", sheet_name="2月销售" # 指定工作表名 ) print("2月销售数据前5行:") print(df_feb.head()) |
案例 2:一次性读取多个工作表
|
# 读取“1月销售”和“2月销售”两个表,返回字典 df_dict = pd.read_excel( "销售数据.xlsx", engine="openpyxl", sheet_name=["1月销售", "2月销售"] ) # 从字典中提取每个表的数据 df_jan = df_dict["1月销售"] # 1月数据 df_feb = df_dict["2月销售"] # 2月数据 print("1月销售数据行数:", len(df_jan)) print("2月销售数据行数:", len(df_feb)) |
3. 处理 Excel 特殊情况:跳过行、合并单元格
情况 1:表头不在第一行(比如前 2 行是注释)
用skiprows跳过前面的行,用header指定表头所在行(从 0 开始):
|
# 跳过前2行(注释),表头在第3行(索引2) df = pd.read_excel( "销售数据.xlsx", engine="openpyxl", skiprows=2, # 跳过前2行 header=2 # 第3行(索引2)作为表头 ) |
情况 2:合并单元格(比如 A1-A3 合并为 “产品信息”)
pandas 读取合并单元格时,只会在 “第一个单元格” 保留值,其他合并单元格会显示NaN(缺失值),需要后续处理,但读取时可以正常加载:
|
# 读取包含合并单元格的Excel,合并单元格会显示NaN df = pd.read_excel("销售数据.xlsx", engine="openpyxl") print("包含合并单元格的数据:") print(df) # 合并单元格的非首格会显示NaN |
四、数据基本信息查看:3 分钟摸清数据 “底细”
加载数据后,第一步不是急于分析,而是 “快速了解数据全貌”—— 比如有多少行多少列、数据类型对不对、有没有缺失值、数值列的范围是什么。pandas 提供了 6 个核心方法,覆盖 90% 的初探需求。
我们用之前的 “销售数据.csv” 加载的 DataFrame(df)为例,逐个讲解:
1. 快速预览:查看前 N 行 / 后 N 行(head ()/tail ())
- df.head(n):查看前 n 行(默认 n=5,适合快速看数据结构);
- df.tail(n):查看后 n 行(默认 n=5,适合看数据末尾是否有异常值)。
|
# 查看前3行 print("前3行数据:") print(df.head(3)) # 输出: # 日期 产品类别 销售额 销量 地区 # 0 2024-01-01 家电 5200 26 华北 # 1 2024-01-02 服装 3800 95 华东 # 2 2024-01-03 家电 6500 32 华南 # 查看后2行 print("\n后2行数据:") print(df.tail(2)) # 输出: # 日期 产品类别 销售额 销量 地区 # 2 2024-01-03 家电 6500 32 华南 # 3 2024-01-04 食品 1200 240 华北 |
2. 数据规模:行数、列数(shape)
df.shape返回一个元组(行数, 列数),快速了解数据体量:
|
print("数据规模(行数, 列数):", df.shape) # 输出:数据规模(行数, 列数): (4, 5) # 单独获取行数、列数 print("行数:", df.shape[0]) # 输出:行数:4 print("列数:", df.shape[1]) # 输出:列数:5 |
3. 列信息:列名、数据类型、缺失值(info ())
df.info()是 “数据初探第一神器”—— 显示列名、每列的数据类型(dtype)、非缺失值数量(Non-Null Count),帮你快速发现问题(比如数值列被识别成文本、有大量缺失值)。
|
print("数据基本信息:") print(df.info()) # 输出: # <class 'pandas.core.frame.DataFrame'> # RangeIndex: 4 entries, 0 to 3 # 行索引:4行,0到3 # Data columns (total 5 columns): # 共5列 # # Column Non-Null Count Dtype # 列索引、列名、非缺失值数、数据类型 # --- ------ -------------- ----- # 0 日期 4 non-null object # object=文本类型(日期默认是文本,后续需转成日期类型) # 1 产品类别 4 non-null object # 文本类型(分类数据) # 2 销售额 4 non-null int64 # 整数类型(数值数据,正常) # 3 销量 4 non-null int64 # 整数类型(数值数据,正常) # 4 地区 4 non-null object # 文本类型(分类数据) # dtypes: int64(2), object(3) # 数据类型统计:2个整数,3个文本 # memory usage: 288.0+ bytes # 内存占用(很小,正常) |
关键解读:
- 数据类型(dtype):
- int64/float64:数值类型(可直接计算);
- object:文本类型(日期、分类等,需根据需求转成对应类型,比如日期转datetime64);
- category:分类类型(适合取值少的列,如 “地区” 只有华北 / 华东 / 华南,后续可转成 category 节省内存)。
- 缺失值(Non-Null Count):如果某列的 “Non-Null Count” 小于总行数(比如总行数 4,某列 3 non-null),说明该列有缺失值(1 个 NaN),后续需要处理。
4. 数值统计:均值、最值、标准差(describe ())
df.describe()对数值列(int64/float64)做统计描述,返回计数、均值、标准差、最小值、四分位数、最大值,帮你快速了解数值分布(比如是否有异常值)。
|
print("数值列统计描述:") print(df.describe()) # 输出(只显示数值列“销售额”和“销量”): # 销售额 销量 # count 4.000000 4.000000 # 计数:4个非缺失值 # mean 4175.000000 98.250000 # 均值:销售额平均4175,销量平均98.25 # std 2237.853883 105.985848 # 标准差:销量标准差大(说明波动大) # min 1200.000000 26.000000 # 最小值:销售额最低1200,销量最低26 # 25% 3150.000000 29.000000 # 25分位数(下四分位) # 50% 4500.000000 63.500000 # 50分位数(中位数) # 75% 5525.000000 126.250000 # 75分位数(上四分位) # max 6500.000000 240.000000 # 最大值:销售额最高6500,销量最高240 |
关键解读:
- 看 “标准差(std)”:如果某列标准差远大于均值(比如销量的 std=105,均值 = 98),说明该列数据波动大(比如销量从 26 到 240,差异大);
- 看 “最值”:是否有明显异常(比如销售额出现负数,或销量出现 10000 这种远超均值的值)。
5. 查看列名和行索引(columns/index)
- df.columns:返回所有列名(可用于遍历列、重命名列);
- df.index:返回行索引(可用于重置索引、修改索引)。
|
# 查看列名(返回Index对象,可转成列表) print("列名:", df.columns.tolist()) # 输出:列名: ['日期', '产品类别', '销售额', '销量', '地区'] # 查看行索引 print("行索引:", df.index.tolist()) # 输出:行索引: [0, 1, 2, 3](默认数字索引) |
6. 分类列唯一值:nunique ()/unique ()
对于 “产品类别”“地区” 这种分类列,用nunique()看有多少个不同值,用unique()看具体是哪些值:
|
# 查看每列的唯一值数量 print("各列唯一值数量:") print(df.nunique()) # 输出: # 日期 4 # 4个不同日期 # 产品类别 3 # 3种产品类别 # 销售额 4 # 4个不同销售额 # 销量 4 # 4个不同销量 # 地区 3 # 3个不同地区 dtype: int64 # 查看“地区”列的具体唯一值 print("\n地区列唯一值:", df["地区"].unique()) # 输出:地区列唯一值: ['华北' '华东' '华南'] # 查看“产品类别”列的唯一值计数(每个类别有多少条数据) print("产品类别计数:") print(df["产品类别"].value_counts()) # 输出: # 产品类别 # 家电 2 # 家电有2条数据 # 服装 1 # 服装有1条数据 # 食品 1 # 食品有1条数据 Name: count, dtype: int64 |
五、实战案例:完整流程(读取→初探)
用一个 “学生成绩.xlsx” 文件,走一遍完整的 “读取→初探” 流程,巩固所学:
1. 数据背景
“学生成绩.xlsx” 包含 1 个工作表 “高一成绩”,数据如下:
|
学号 |
姓名 |
语文 |
数学 |
英语 |
班级 |
|
2024001 |
张三 |
85 |
92 |
78 |
1 班 |
|
2024002 |
李四 |
76 |
68 |
89 |
2 班 |
|
2024003 |
王五 |
90 |
95 |
92 |
1 班 |
|
2024004 |
赵六 |
65 |
58 |
72 |
2 班 |
|
2024005 |
孙七 |
88 |
79 |
85 |
1 班 |
2. 完整代码
|
import pandas as pd # 1. 读取Excel文件(指定工作表“高一成绩”,用学号做行索引) df_score = pd.read_excel( "学生成绩.xlsx", engine="openpyxl", sheet_name="高一成绩", index_col="学号" # 用学号做行索引(唯一标识) ) # 2. 数据初探 print("=" * 40) print("1. 数据规模(行数, 列数):", df_score.shape) print("=" * 40) print("2. 前3行数据:") print(df_score.head(3)) print("=" * 40) print("3. 数据类型和缺失值:") print(df_score.info()) print("=" * 40) print("4. 成绩统计描述(数值列):") print(df_score.describe()) print("=" * 40) print("5. 班级分布(分类列):") print(df_score["班级"].value_counts()) print("=" * 40) print("6. 语文成绩最高分:", df_score["语文"].max()) print("数学成绩最低分:", df_score["数学"].min()) print("英语成绩平均分:", df_score["英语"].mean().round(1)) # 保留1位小数 |
3. 运行结果解读
|
======================================== 1. 数据规模(行数, 列数): (5, 5) ======================================== 2. 前3行数据: 姓名 语文 数学 英语 班级 学号 2024001 张三 85 92 78 1班 2024002 李四 76 68 89 2班 2024003 王五 90 95 92 1班 ======================================== 3. 数据类型和缺失值: <class 'pandas.core.frame.DataFrame'> Index: 5 entries, 2024001 to 2024005 # 行索引是学号 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 姓名 5 non-null object 1 语文 5 non-null int64 2 数学 5 non-null int64 3 英语 5 non-null int64 4 班级 5 non-null object dtypes: int64(3), object(2) memory usage: 240.0+ bytes ======================================== 4. 成绩统计描述(数值列): 语文 数学 英语 count 5.000000 5.000000 5.000000 mean 80.800000 78.400000 83.200000 std 10.382689 14.177446 8.508819 min 65.000000 58.000000 72.000000 25% 76.000000 68.000000 78.000000 50% 85.000000 79.000000 85.000000 75% 88.000000 92.000000 89.000000 max 90.000000 95.000000 92.000000 ======================================== 5. 班级分布(分类列): 班级 1班 3 2班 2 Name: count, dtype: int64 ======================================== 6. 语文成绩最高分: 90 数学成绩最低分: 58 英语成绩平均分: 83.2 |
通过这个流程,我们快速知道:
- 数据有 5 个学生,5 列信息(姓名、3 科成绩、班级);
- 无缺失值,成绩都是整数类型(正常);
- 数学成绩波动最大(std=14.2),最低分 58(可能需要关注);
- 1 班有 3 人,2 班有 2 人。
六、新手常见问题解决(踩坑指南)
1. 读取文件时提示 “文件不存在”
- 原因 1:文件路径写错(比如把 “销售数据.csv” 写成 “销售.csv”);
- 原因 2:文件不在代码同一目录,且没写绝对路径;
- 解决:
① 确认文件名和后缀(.csv/.xlsx)完全正确;
② 若文件不在代码目录,写绝对路径(比如 Windows:"C:/Users/XXX/Desktop/销售数据.csv",Mac:"/Users/XXX/Desktop/销售数据.csv");
③ 推荐:把文件和代码放在同一目录,直接写文件名(最简单,不易错)。
2. 读取 Excel 时提示 “No module named 'openpyxl'”
- 原因:没装 openpyxl 库,或安装失败;
- 解决:重新执行pip install openpyxl,确保安装成功(看到 “Successfully installed openpyxl-xxx”)。
3. 读取 CSV 中文乱码,试了 utf-8 和 gbk 都不行
- 原因:文件编码是其他格式(比如 gb2312、utf-16);
- 解决:用记事本打开 CSV 文件→点击 “文件→另存为”→查看 “编码” 选项(比如显示 “ANSI”,对应 gbk;显示 “UTF-8” 对应 utf-8),按实际编码填写encoding参数。
4. describe () 只显示部分列
- 原因:describe () 默认只统计数值列(int64/float64),文本列(object)不显示;
- 解决:若想统计文本列,加include="all"参数:df.describe(include="all"),会显示文本列的唯一值数量、最频繁值等信息。
七、总结与后续学习方向
今天我们掌握了数据分析的 “第一步核心技能”:
- 用 pandas 读取 CSV(解决中文乱码、指定列)和 Excel(指定工作表、处理特殊格式);
- 用 6 个方法快速初探数据(head ()/info ()/describe () 等),摸清数据规模、类型、缺失值、分布;
下一步可以学习:
- 数据清洗:处理缺失值(填充 / 删除)、异常值(识别 / 修正)、数据类型转换(比如把文本日期转成 datetime);
- 数据筛选与分组:用df.loc[]筛选数据,用df.groupby()按分类列分组统计(比如按班级统计平均成绩);
- 数据可视化:结合 matplotlib/seaborn 画柱状图、折线图(比如展示各班级成绩分布)。
如果在读取数据或初探时遇到具体问题,欢迎留言分享你的数据格式和报错信息,我会帮你针对性解决!
更多推荐


所有评论(0)