目录
二、环境搭建与核心数据结构:从安装到认识 pandas 的 “基本单位”
2.2.2 DataFrame:“表格型数据” 的核心(重点)

class 卑微码农:
def __init__(self):
self.技能 = ['能读懂十年前祖传代码', '擅长用Ctrl+C/V搭建世界', '信奉"能跑就别动"的玄学']
self.发量 = 100 # 初始发量
self.咖啡因耐受度 = '极限'
def 修Bug(self, bug):
try:
# 试图用玄学解决问题
if bug.严重程度 == '离谱':
print("这一定是环境问题!")
else:
print("让我看看是谁又没写注释...哦,是我自己。")
except Exception as e:
# 如果try块都救不了,那就...
print("重启一下试试?")
self.发量 -= 1 # 每解决一个bug,头发-1
# 实例化一个我
我 = 卑微码农()
引言
在数据分析领域,你是否遇到过这些场景:用 Excel 处理十万行数据时卡顿崩溃?用 Python 原生列表嵌套字典处理表格数据写得手发麻?想快速按类别统计数据却要写几十行循环?而 pandas—— 这款基于 NumPy 的 Python 数据分析库,正是为解决这些问题而生。

它能像 Excel 一样直观操作表格数据,却比 Excel 快 100 倍;它能一行代码完成原本需要几十行循环的统计工作,让数据处理效率呈指数级提升。无论是清洗杂乱的原始数据、按条件筛选信息,还是分组聚合分析、生成可视化图表,pandas 都是数据分析师的 “瑞士军刀”。
本文从实际业务场景出发,通过 “基础操作→数据清洗→高级分析→可视化” 的递进结构,搭配可直接运行的代码示例(附数据集说明),帮你从零基础掌握 pandas 核心技能,轻松应对 90% 以上的数据分析场景。
一、为什么 pandas 是数据分析的 “必备神器”?

在 pandas 出现之前,处理结构化数据(如表格、CSV)的方式都有明显短板:
- Excel/Google Sheets:适合轻量数据,但处理 10 万行以上数据时卡顿严重,复杂逻辑需写冗长公式,且难以自动化重复工作;
- Python 原生数据结构:用列表、字典存储表格数据,筛选、分组需手动写循环,代码繁琐且效率低;
- SQL:适合数据库查询,但缺乏数据清洗、格式转换、可视化等一站式能力。
而 pandas 的核心优势在于 “结构化数据的高效操作”,它能:
- 快速处理大规模数据:轻松应对百万级行数,比 Excel 快 10-100 倍;
- 简洁语法实现复杂逻辑:一行代码完成筛选、分组、合并等操作,替代几十行循环;
- 兼容多种数据格式:直接读取 CSV、Excel、JSON、数据库等来源的数据;
- 无缝衔接可视化工具:与 matplotlib、seaborn 等库联动,快速生成图表;
- 可自动化重复流程:通过脚本批量处理数据,摆脱手动操作。
无论是电商销售数据统计、用户行为分析,还是科研数据处理、金融风控建模,pandas 都是数据处理环节的 “第一站”。
二、环境搭建与核心数据结构:从安装到认识 pandas 的 “基本单位”

2.1 安装 pandas:3 行命令搞定环境
pandas 依赖 NumPy,建议用 Anaconda 或 pip 安装(推荐 Python 3.8 + 版本):
# 方式1:pip安装(确保pip是最新版本)
pip install --upgrade pip
pip install pandas numpy # numpy是pandas的依赖,需同时安装
# 方式2:Anaconda安装(自带pandas,若未安装则执行)
conda install pandas
验证安装是否成功:
import pandas as pd # 约定俗成的简写,必须记住
import numpy as np
print(pd.__version__) # 输出pandas版本,如'2.1.4'则安装成功
2.2 核心数据结构:Series 与 DataFrame
pandas 有两个核心数据结构,所有操作都围绕它们展开,必须先吃透:
2.2.1 Series:带索引的 “增强版数组”
Series 是一维数据结构,类似 “带标签的数组”—— 既有数据值(value),又有对应的索引(index)。可以理解为 “只有一列的表格”,或 “带名字的列表”。
创建 Series:
import pandas as pd
# 从列表创建(默认索引是0,1,2...)
s1 = pd.Series([10, 20, 30, 40])
print(s1)
# 输出:
# 0 10
# 1 20
# 2 30
# 3 40
# dtype: int64 # 数据类型
# 自定义索引(索引可以是字符串、数字等)
s2 = pd.Series(
data=[85, 92, 78], # 数据
index=['数学', '语文', '英语'], # 索引(标签)
name='成绩' # 给Series起个名字(类似列名)
)
print(s2)
# 输出:
# 数学 85
# 语文 92
# 英语 78
# Name: 成绩, dtype: int64
访问 Series 数据:
# 按索引访问(类似字典的key)
print(s2['语文']) # 输出:92
# 按位置访问(类似列表的下标)
print(s2.iloc[0]) # 输出:85(第0个元素)
# 切片访问
print(s2[['数学', '英语']]) # 输出数学和英语成绩
2.2.2 DataFrame:“表格型数据” 的核心(重点)
DataFrame 是二维数据结构,相当于 “带索引的表格”—— 有行索引(index)、列名(columns),以及单元格数据。这是 pandas 中最常用的数据结构,90% 的操作都围绕它展开。
可以把 DataFrame 理解为:
- 多个 Series 组成的集合(共用同一个行索引);
- Excel 中的工作表(Sheet);
- 数据库中的表(Table)。
创建 DataFrame:
import pandas as pd
# 从字典创建(最常用):key是列名,value是列数据(列表/Series)
data = {
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [20, 22, 21, 19],
'专业': ['计算机', '数学', '计算机', '英语'],
'成绩': [85, 90, 88, 92]
}
df = pd.DataFrame(data)
print(df)
# 输出:
# 姓名 年龄 专业 成绩
# 0 张三 20 计算机 85
# 1 李四 22 数学 90
# 2 王五 21 计算机 88
# 3 赵六 19 英语 92
DataFrame 的基本属性:
print(df.shape) # 输出:(4, 4) → 4行4列
print(df.columns) # 输出列名:Index(['姓名', '年龄', '专业', '成绩'], dtype='object')
print(df.index) # 输出行索引:RangeIndex(start=0, stop=4, step=1)
print(df.dtypes) # 输出各列数据类型:姓名object(字符串)、年龄int64、专业object、成绩int64
快速查看数据:
print(df.head(2)) # 查看前2行(默认5行)
print(df.tail(1)) # 查看最后1行
print(df.info()) # 查看数据概览(行数、列数、数据类型、缺失值等)
print(df.describe()) # 对数值列(年龄、成绩)做统计分析(均值、标准差、最值等)
三、数据读取与写入:搞定 90% 的数据源

实际分析中,数据往往存储在文件或数据库中。pandas 支持多种格式的读写,最常用的是 CSV 和 Excel。
3.1 读取数据:从文件到 DataFrame
3.1.1 读取 CSV 文件(最常用)
CSV(逗号分隔值)是数据交换的标准格式,读取速度快,推荐优先使用。
# 读取本地CSV文件(假设文件在当前目录)
df = pd.read_csv('sales_data.csv') # sales_data.csv是示例文件名
# 读取带表头的CSV(默认第一行为表头)
# 若CSV无表头,用header=None,再手动指定列名:
df = pd.read_csv('no_header.csv', header=None, names=['日期', '销售额', '地区'])
# 常用参数:
# sep:指定分隔符(默认逗号,如用\t分隔则sep='\t')
# encoding:指定编码(中文常用'utf-8'或'gbk')
# usecols:只读取指定列(如usecols=['日期', '销售额'])
# parse_dates:将指定列解析为日期格式(如parse_dates=['日期'])
df = pd.read_csv(
'sales_data.csv',
encoding='utf-8', # 处理中文
parse_dates=['成交日期'], # 自动解析日期列
usecols=['成交日期', '商品名称', '销售额', '地区'] # 只读取这4列
)
3.1.2 读取 Excel 文件
读取 Excel 需要额外安装openpyxl(处理.xlsx)或xlrd(处理.xls):
pip install openpyxl # 安装依赖
运行
# 读取Excel文件(默认读第一个Sheet)
df = pd.read_excel('student_scores.xlsx')
# 读取指定Sheet(用sheet_name参数)
df = pd.read_excel(
'student_scores.xlsx',
sheet_name='高一(1)班', # 按Sheet名读取
# 或 sheet_name=0 按索引读取(0是第一个Sheet)
header=0, # 第0行作为表头
skiprows=2 # 跳过前2行(从第3行开始读)
)
3.2 写入数据:从 DataFrame 到文件
处理完的数据通常需要保存为文件,方便后续使用或分享。
3.2.1 写入 CSV
# 将DataFrame写入CSV(index=False表示不保存行索引)
df.to_csv('processed_sales.csv', index=False, encoding='utf-8')
# 常用参数:
# index:是否保存行索引(默认True,建议设为False)
# columns:只保存指定列(如columns=['姓名', '成绩'])
# na_rep:缺失值用什么符号表示(如na_rep='未知')
df.to_csv(
'filtered_data.csv',
index=False,
columns=['商品名称', '销售额'],
na_rep='暂无数据'
)
3.2.2 写入 Excel
# 写入Excel(需安装openpyxl)
df.to_excel('result.xlsx', index=False, sheet_name='分析结果')
# 写入多个Sheet到同一个Excel文件
with pd.ExcelWriter('multi_sheet.xlsx') as writer:
df1.to_excel(writer, sheet_name='Sheet1', index=False)
df2.to_excel(writer, sheet_name='Sheet2', index=False)
四、数据清洗:让 “脏数据” 变 “干净”

实际业务中的数据往往是 “脏” 的 —— 有缺失值、重复值、格式错误等。数据清洗是数据分析的第一步,也是最耗时的一步(占整个分析流程的 60% 以上)。
4.1 处理缺失值:填补或删除
缺失值(NaN/None)会影响分析结果,必须处理。常见策略:删除含缺失值的行 / 列,或用合理值填充。
4.1.1 检测缺失值
# 查看每列缺失值数量
print(df.isnull().sum())
# 输出示例:
# 姓名 0
# 年龄 1
# 专业 0
# 成绩 2
# dtype: int64
# 查看哪些行有缺失值
print(df[df.isnull().any(axis=1)]) # 显示至少有一个缺失值的行
4.1.2 删除缺失值
# 删除所有含缺失值的行(默认axis=0,how='any')
df_clean = df.dropna() # 等价于df.dropna(axis=0, how='any')
# 只删除全是缺失值的行
df_clean = df.dropna(how='all')
# 删除指定列有缺失值的行(如只删除“成绩”列缺失的行)
df_clean = df.dropna(subset=['成绩'])
# 删除缺失值比例超过50%的列
thresh = len(df) * 0.5 # 至少有50%的非缺失值才保留
df_clean = df.dropna(axis=1, thresh=thresh)
4.1.3 填充缺失值(更常用)
删除会丢失数据,实际中更常用填充法:
# 用固定值填充(如用0填充所有缺失值)
df_fill = df.fillna(0)
# 按列填充(不同列用不同值)
df_fill = df.fillna({
'年龄': 20, # 年龄缺失用20填充
'成绩': 60 # 成绩缺失用60填充
})
# 用均值/中位数填充数值列(推荐)
df['年龄'] = df['年龄'].fillna(df['年龄'].mean()) # 年龄用均值填充
df['成绩'] = df['成绩'].fillna(df['成绩'].median()) # 成绩用中位数填充
# 用前一个值填充(适用于时间序列数据)
df['销售额'] = df['销售额'].fillna(method='ffill') # forward fill:向前填充
# 用后一个值填充
df['销售额'] = df['销售额'].fillna(method='bfill') # backward fill:向后填充
4.2 处理重复值:去重
重复数据会导致分析结果偏差(如统计时重复计算),需要去重。
# 检测重复行(判断所有列都相同的行)
print(df.duplicated()) # 返回布尔Series,True表示重复行
# 查看重复行
print(df[df.duplicated()])
# 删除重复行(默认保留第一行)
df_unique = df.drop_duplicates()
# 按指定列去重(如“姓名”和“日期”都相同才视为重复)
df_unique = df.drop_duplicates(subset=['姓名', '日期'], keep='last') # keep='last'保留最后一行
4.3 数据类型转换:让数据 “各司其职”
pandas 会自动推断数据类型,但有时会出错(如把数字型 ID 识别为字符串),需要手动转换。
# 查看当前数据类型
print(df.dtypes)
# 1. 转换为数值型(int/float)
# 场景:“销售额”列被识别为字符串(因含逗号等符号)
df['销售额'] = df['销售额'].replace(',', '', regex=True) # 先去除逗号
df['销售额'] = df['销售额'].astype(float) # 转为float
# 2. 转换为日期型(关键!时间序列分析必备)
# 场景:“成交日期”列是字符串(如'2023-10-01')
df['成交日期'] = pd.to_datetime(df['成交日期']) # 自动解析为datetime类型
# 3. 转换为分类类型(适合枚举值,如“地区”“性别”)
# 优势:减少内存占用,提高分组效率
df['地区'] = df['地区'].astype('category')
print(df['地区'].cat.categories) # 查看分类值:['北京', '上海', '广州']
4.4 数据格式清洗:标准化数据
实际数据常存在格式不统一(如日期格式混乱、字符串大小写不一致),需要标准化。
# 1. 字符串处理(如统一姓名大小写)
df['姓名'] = df['姓名'].str.strip() # 去除前后空格
df['姓名'] = df['姓名'].str.title() # 首字母大写(如'zhang san'→'Zhang San')
# 2. 提取字符串中的关键信息(如从邮箱提取域名)
df['邮箱域名'] = df['邮箱'].str.split('@').str[1] # 按@分割,取第2部分
# 3. 替换异常值(如把“-”替换为0)
df['销量'] = df['销量'].replace('-', 0)
# 4. 日期格式标准化(如把'10/01/23'统一为'2023-10-01')
df['日期'] = pd.to_datetime(df['日期'], format='%m/%d/%y') # 指定输入格式
五、数据筛选与查询:精准提取所需信息

拿到干净的数据后,下一步是按条件提取信息(如 “找出成绩大于 90 分的计算机专业学生”)。pandas 提供了多种灵活的筛选方式。
5.1 按列筛选:选择需要的列
# 选择单列(返回Series)
names = df['姓名']
# 选择多列(返回DataFrame,传入列名列表)
score_df = df[['姓名', '专业', '成绩']]
5.2 按行筛选:按条件过滤行
5.2.1 单条件筛选
# 筛选成绩大于90分的行
high_score = df[df['成绩'] > 90]
# 筛选专业为“计算机”的行
cs_majors = df[df['专业'] == '计算机']
# 筛选年龄在20-22岁之间的行(含边界)
age_filter = df[(df['年龄'] >= 20) & (df['年龄'] <= 22)] # 注意用&,不是and
5.2.2 多条件筛选
# 条件1:专业是计算机;条件2:成绩>85(同时满足)
cs_high = df[(df['专业'] == '计算机') & (df['成绩'] > 85)]
# 条件1:年龄<20;条件2:成绩>90(满足其一)
young_or_excellent = df[(df['年龄'] < 20) | (df['成绩'] > 90)] # 用|,不是or
# 筛选专业在列表中的行(如计算机、数学)
target_majors = df[df['专业'].isin(['计算机', '数学'])]
# 筛选成绩不在60-80之间的行(取反用~)
not_mid = df[~df['成绩'].between(60, 80)] # ~表示否定
5.3 按位置 / 标签筛选:loc 与 iloc(重点)
pandas 提供了两个高效的筛选方法:
loc:按标签(行索引、列名)筛选;iloc:按位置(行号、列号,从 0 开始)筛选。
5.3.1 loc:按标签筛选
# 语法:df.loc[行标签条件, 列名]
# 选择行标签为0-2的行,列名为'姓名'和'成绩'
df.loc[0:2, ['姓名', '成绩']]
# 按条件选行,同时指定列
df.loc[df['成绩'] > 90, ['姓名', '专业']]
# 修改满足条件的行的某列值(如给计算机专业学生成绩+5分)
df.loc[df['专业'] == '计算机', '成绩'] += 5
5.3.2 iloc:按位置筛选
# 语法:df.iloc[行位置, 列位置]
# 选择前3行,前2列(行0-2,列0-1)
df.iloc[0:3, 0:2] # 注意:iloc的切片是左闭右开(0:3包含0,1,2)
# 选择第0行和第2行,第1列和第3列
df.iloc[[0, 2], [1, 3]]
# 选择所有行,第2列之后的列
df.iloc[:, 2:]
5.4 复杂查询:query 方法(更简洁)
对于多条件筛选,query方法用字符串表示条件,语法更接近自然语言:
# 筛选专业为计算机且成绩>85的学生
cs_high = df.query("专业 == '计算机' and 成绩 > 85")
# 筛选年龄<20或成绩>90的学生
young_or_excellent = df.query("年龄 < 20 or 成绩 > 90")
# 用变量作为条件(需加@符号)
min_score = 80
df.query("成绩 >= @min_score") # 成绩大于等于min_score
六、数据分组与聚合:按类别分析数据

分组聚合是数据分析的核心操作 —— 按某个类别(如地区、专业)分组,然后计算每组的统计量(如平均值、总和)。比如 “按地区分组,计算每个地区的总销售额”。
6.1 分组基础:groupby 方法
# 按“专业”分组(返回GroupBy对象,需配合聚合函数使用)
grouped = df.groupby('专业')
# 查看分组情况(每组的行数)
print(grouped.size())
# 输出示例:
# 专业
# 计算机 2
# 数学 1
# 英语 1
# dtype: int64
6.2 常用聚合函数:计算统计量
对分组后的数据应用聚合函数(sum、mean、count 等):
# 按专业分组,计算每组成绩的平均值
major_avg = df.groupby('专业')['成绩'].mean()
print(major_avg)
# 输出示例:
# 专业
# 计算机 86.5
# 数学 90.0
# 英语 92.0
# Name: 成绩, dtype: float64
# 按专业分组,计算成绩的总和、均值、最大值
major_stats = df.groupby('专业')['成绩'].agg(['sum', 'mean', 'max'])
print(major_stats)
# 输出示例:
# sum mean max
# 专业
# 计算机 173 86.5 88
# 数学 90 90.0 90
# 英语 92 92.0 92
# 对不同列用不同聚合函数(如年龄求均值,成绩求总和)
multi_agg = df.groupby('专业').agg(
平均年龄=('年龄', 'mean'),
总分数=('成绩', 'sum')
)
print(multi_agg)
6.3 多级分组:更细致的分析
按多个列分组(如先按地区,再按商品类别):
# 按“地区”和“商品类别”两级分组,计算销售额总和
sales_group = df.groupby(['地区', '商品类别'])['销售额'].sum()
print(sales_group)
# 输出示例:
# 地区 商品类别
# 北京 电子产品 15000
# 服装 8000
# 上海 电子产品 20000
# 服装 6000
# Name: 销售额, dtype: float64
# 重置索引(将多级索引转为普通列)
sales_df = sales_group.reset_index()
6.4 分组后的数据转换:transform
transform能对每组数据做转换(如标准化、填充),并返回与原数据长度相同的结果:
# 按专业分组,计算每组成绩的均值,然后用“成绩-组均值”得到偏差值
df['成绩偏差'] = df.groupby('专业')['成绩'].transform(
lambda x: x - x.mean()
)
print(df[['姓名', '专业', '成绩', '成绩偏差']])
# 输出示例:
# 姓名 专业 成绩 成绩偏差
# 0 张三 计算机 85 -1.5
# 1 李四 数学 90 0.0
# 2 王五 计算机 88 1.5
# 3 赵六 英语 92 0.0
七、数据合并:多表关联分析

实际分析中,数据常分散在多个表中(如 “用户表” 和 “订单表”),需要合并后分析。pandas 提供了类似 SQL 的合并功能。
7.1 拼接:上下 / 左右拼接(concat)
适合结构相似的表(如多个月份的销售数据):
# 示例数据:两个月的销售表
df1 = pd.DataFrame({'日期': ['2023-10-01', '2023-10-02'], '销售额': [1000, 1200]})
df2 = pd.DataFrame({'日期': ['2023-11-01', '2023-11-02'], '销售额': [1500, 1300]})
# 上下拼接(行方向,axis=0)
df_all = pd.concat([df1, df2], axis=0, ignore_index=True) # ignore_index重置行索引
print(df_all)
# 输出:
# 日期 销售额
# 0 2023-10-01 1000
# 1 2023-10-02 1200
# 2 2023-11-01 1500
# 3 2023-11-02 1300
# 左右拼接(列方向,axis=1)
df3 = pd.DataFrame({'日期': ['2023-10-01', '2023-10-02'], '销量': [50, 60]})
df_combined = pd.concat([df1, df3], axis=1) # 按行索引对齐
7.2 合并:按关键字关联(merge)
类似 SQL 的 JOIN,按共同列(关键字)合并表:
# 示例数据:用户表和订单表
users = pd.DataFrame({
'用户ID': [1, 2, 3],
'姓名': ['张三', '李四', '王五'],
'地区': ['北京', '上海', '北京']
})
orders = pd.DataFrame({
'订单ID': [101, 102, 103],
'用户ID': [1, 1, 2], # 外键,关联用户表
'金额': [200, 300, 150]
})
# 内连接(只保留两边都有的用户ID)
inner_join = pd.merge(users, orders, on='用户ID', how='inner')
print(inner_join)
# 输出:
# 用户ID 姓名 地区 订单ID 金额
# 0 1 张三 北京 101 200
# 1 1 张三 北京 102 300
# 2 2 李四 上海 103 150
# 左连接(保留用户表所有用户,订单表没有的用NaN)
left_join = pd.merge(users, orders, on='用户ID', how='left')
print(left_join)
# 输出:
# 用户ID 姓名 地区 订单ID 金额
# 0 1 张三 北京 101.0 200.0
# 1 1 张三 北京 102.0 300.0
# 2 2 李四 上海 103.0 150.0
# 3 3 王五 北京 NaN NaN
how参数可选:inner(内连接)、left(左连接)、right(右连接)、outer(外连接)。
八、数据可视化:让分析结果 “看得见”

pandas 内置了可视化功能(基于 matplotlib),能快速将数据转为图表,直观展示分析结果。
8.1 安装可视化依赖
pip install matplotlib seaborn # seaborn让图表更美观
8.2 常用图表类型
8.2.1 折线图:展示趋势(如销售额随时间变化)
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid') # 设置图表风格
# 假设df有“日期”和“销售额”列,且日期已转为datetime类型
df['日期'] = pd.to_datetime(df['日期'])
df.plot(x='日期', y='销售额', kind='line', figsize=(10, 5))
plt.title('每日销售额趋势') # 标题
plt.xlabel('日期') # x轴标签
plt.ylabel('销售额(元)') # y轴标签
plt.show()
8.2.2 柱状图:比较类别数据(如各地区销售额)
# 按地区分组计算总销售额,然后画柱状图
region_sales = df.groupby('地区')['销售额'].sum()
region_sales.plot(kind='bar', color='skyblue', figsize=(8, 5))
plt.title('各地区总销售额')
plt.xticks(rotation=0) # x轴标签不旋转
plt.show()
8.2.3 直方图:展示数据分布(如成绩分布)
# 画成绩的直方图,看分数分布
df['成绩'].plot(kind='hist', bins=10, color='orange', figsize=(8, 5)) # bins是 bins数量
plt.title('成绩分布直方图')
plt.xlabel('成绩')
plt.show()
8.2.4 散点图:看变量相关性(如广告投入与销售额)
# 看广告投入与销售额的关系
df.plot(x='广告投入', y='销售额', kind='scatter', color='green', figsize=(8, 5))
plt.title('广告投入与销售额相关性')
plt.show() # 若点呈上升趋势,说明正相关
九、实战案例:电商销售数据分析全流程

以 “某电商平台 10 月销售数据” 为例,完整演示从数据读取到分析可视化的流程。
9.1 数据说明
数据文件sales_october.csv包含以下字段:
订单ID:订单唯一标识用户ID:用户唯一标识商品类别:如 “电子产品”“服装” 等地区:用户所在地区(北京 / 上海 / 广州 / 深圳)成交日期:订单成交时间销售额:订单金额(元)销量:订单商品数量
9.2 分析目标
- 清洗数据(处理缺失值、异常值);
- 分析各地区销售额占比;
- 分析不同商品类别的销量与销售额;
- 查看每日销售额趋势;
- 找出销售额最高的前 10 个订单。
9.3 代码实现
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')
# 1. 读取数据
df = pd.read_csv(
'sales_october.csv',
parse_dates=['成交日期'], # 解析日期
encoding='utf-8'
)
# 2. 数据清洗
# 查看数据概览
print("原始数据形状:", df.shape)
print(df.info())
print("缺失值情况:\n", df.isnull().sum())
# 处理缺失值(假设“销售额”缺失用均值填充,其他列缺失删除)
df['销售额'] = df['销售额'].fillna(df['销售额'].mean())
df = df.dropna(subset=['用户ID', '商品类别']) # 删除关键列缺失的行
# 处理异常值(销售额不能为负)
df = df[df['销售额'] >= 0]
print("清洗后数据形状:", df.shape)
# 3. 各地区销售额占比分析
region_sales = df.groupby('地区')['销售额'].sum().sort_values(ascending=False)
plt.figure(figsize=(8, 8))
plt.pie(
region_sales,
labels=region_sales.index,
autopct='%.1f%%', # 显示百分比
startangle=90
)
plt.title('10月各地区销售额占比')
plt.show()
# 4. 商品类别分析(销量与销售额)
category_stats = df.groupby('商品类别').agg(
总销量=('销量', 'sum'),
总销售额=('销售额', 'sum')
).sort_values('总销售额', ascending=False)
# 画柱状图对比
category_stats.plot(kind='bar', figsize=(12, 6))
plt.title('各商品类别销量与销售额对比')
plt.xticks(rotation=45)
plt.show()
# 5. 每日销售额趋势
daily_sales = df.groupby('成交日期')['销售额'].sum()
daily_sales.plot(kind='line', figsize=(12, 6), color='red')
plt.title('10月每日销售额趋势')
plt.xlabel('日期')
plt.ylabel('销售额(元)')
plt.show()
# 6. 销售额前10的订单
top10_orders = df.sort_values('销售额', ascending=False).head(10)
print("销售额前10的订单:")
print(top10_orders[['订单ID', '用户ID', '商品类别', '地区', '销售额']])
9.4 分析结论(示例)
- 上海地区销售额占比最高(35.2%),其次是北京(28.7%);
- 电子产品是销售额最高的类别(占比 42%),但服装类销量最高;
- 10 月 15 日和 30 日出现销售额高峰(可能与促销活动有关);
- 订单 ID 为 8921 的订单销售额最高(12500 元),来自上海的电子产品订单。
十、避坑指南:pandas 新手常犯的 8 个错误

1. 忽略数据类型,导致计算错误
错误:把字符串类型的 “销售额” 直接用于计算(如df['销售额'].sum()返回字符串拼接结果)。解决:先转为数值型:df['销售额'] = pd.to_numeric(df['销售额'])。
2. 误用inplace=True导致数据丢失
错误:df.dropna(inplace=True)后想恢复原始数据,发现已被修改。解决:尽量不用inplace=True,而是赋值给新变量:df_clean = df.dropna()。
3. 处理大型数据时内存不足
错误:直接读取 100 万行的 CSV,导致内存溢出。解决:分批读取:df = pd.read_csv('big_data.csv', chunksize=10000),再逐块处理。
4. 索引混乱导致筛选错误
错误:用df[df['成绩']>90][0:2]筛选,因索引不连续导致结果错误。解决:用loc或iloc:df.loc[df['成绩']>90].iloc[0:2]。
5. 日期处理不当,无法按时间筛选
错误:把日期当字符串处理,无法按月份 / 季度分组。解决:用pd.to_datetime()转为日期型,再提取时间组件:df['月份'] = df['成交日期'].dt.month。
6. 分组后直接修改原数据
错误:df.groupby('专业')['成绩'].mean() = 80(试图直接修改分组结果)。解决:用transform或apply修改原数据,或保存分组结果到新变量。
7. 合并表时忽略重复列名
错误:合并两个有相同列名(非关键字)的表,导致列名被自动添加后缀(如_x、_y)。解决:合并前重命名列:df1.rename(columns={'金额': '订单金额'})。
8. 可视化时中文显示乱码
错误:图表中中文显示为方框或乱码。解决:设置 matplotlib 字体:
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
十一、总结:pandas 学习路径与进阶建议
核心知识点回顾
- 基础操作:Series 与 DataFrame 的创建、属性查看、数据读写;
- 数据清洗:缺失值 / 重复值处理、数据类型转换、格式标准化;
- 数据查询:按列 / 行筛选、loc/iloc 精准查询、query 多条件筛选;
- 分组聚合:groupby 分组、agg 聚合、transform 数据转换;
- 数据合并:concat 拼接、merge 关联;
- 可视化:折线图 / 柱状图 / 饼图等基本图表绘制。
进阶学习建议
- 性能优化:学习
astype转换数据类型减少内存、eval/query提升复杂计算效率、矢量化操作替代循环; - 时间序列:深入学习
DatetimeIndex、滑动窗口(rolling)、时间重采样(resample); - 高级功能:掌握
pivot_table数据透视表、melt数据重塑、apply自定义函数; - 结合其他库:学习与 NumPy(数值计算)、Matplotlib/Seaborn(可视化)、Scikit-learn(机器学习)的协同使用。
pandas 的学习核心是 “多用多练”—— 找一份实际数据(如自己的消费记录、公开数据集),尝试清洗、分析、可视化,遇到问题查官方文档(pandas 官方文档)。从处理 100 行数据到 100 万行数据,你会逐渐体会到它的强大之处。
1035

被折叠的 条评论
为什么被折叠?



