Python商务数据分析——CHAPTER4-Pandas 数据分析全攻略
一、Pandas 基础认知
1.1 Pandas 库核心特性
- 底层依赖:基于 NumPy 数组构建,支持直接调用 NumPy 函数
- 数据结构:提供 Series(一维)和 DataFrame(二维表格)数据结构
- 功能覆盖:数据过滤、清洗、合并、重塑,支持 CSV/Excel/SQL 等格式输入输出
- 应用场景:大规模数据处理效率远超 Excel,是 Python 数据科学生态核心库
1.2 安装与环境配置
1.2.1 命令行安装
# 标准安装命令(Windows/macOS通用)pip install pandas
1.2.2 标准导入方式
import numpy as np
import pandas as pd # 约定俗成别名
二、核心数据结构详解
2.1 Series(一维标签数组)
2.1.1 创建方式汇总
创建方式 | 代码示例 | 输出结果 |
列表创建 | s_list = pd.Series([11, 22, 33, 44]) | 0 11\n1 22\n2 33\n3 44\ndtype: int64 |
字典创建 | s_dict = pd.Series({'a':3.2, 'b':7.6}) | a 3.20\nb 7.60\ndtype: float64 |
Numpy 数组创建 | num = np.random.randn(4)\ns_np = pd.Series(num, index=['a','b','c','d']) | a -0.1234\nb 0.5678\nc -0.9123\nd 0.3456\ndtype: float64 |
标量创建 | s_scalar = pd.Series(7, index=['a','b','c']) | a 7\nb 7\nc 7\ndtype: int64 |
2.1.2 常用属性说明
s = pd.Series([1, 2, 3, 4], index=['w', 'x', 'y', 'z'])
print(f"索引列表:{s.axes}") # [Index(['w', 'x', 'y', 'z'], dtype='object')]
print(f"数据类型:{s.dtype}") # int64
print(f"数据维度:{s.ndim}") # 1
print(f"数据形状:{s.shape}") # (4,)
print(f"元素数量:{s.size}") # 4
print(f"值数组:{s.values}") # array([1, 2, 3, 4], dtype=int64)
2.2 DataFrame(二维表格结构)
2.2.1 多场景创建示例
2.2.1.1 字典创建
df_dict = pd.DataFrame({
'姓名': ['张三', '李四'],
'年龄': [22, 18],
'性别': ['女', '女']
})
输出结果
姓名 年龄 性别
0 张三 22 女
1 李四 18 女
2.2.1.2 CSV 文件读取
# 假设文件路径正确,index_col指定行索引列
df_csv = pd.read_csv('data/北京积分落户数据.csv', index_col='id')
输出示例(前 3 行)
姓名 生日 公司 积分
id
1 杨x 1972-12 北京利德xxx 122.59
2 纪x 1974-12 北京航天xxx 121.25
3 王x 1974-05 品牌联盟xxx 118.96
2.2.1.3 Excel 文件读取
# 读取指定工作表并筛选列
df_excel = pd.read_excel(
'data/某药房2018年销售数据.xlsx',
usecols=['购药时间', '销售数量']
)
2.2.2 关键属性与方法
操作 | 代码示例 | 输出说明 |
转置 | df.T | 行列互换,适用于数据结构查看 |
前 N 行 | df.head(3) | 返回前 3 行数据,默认 N=5 |
数据类型 | df.dtypes | 各列数据类型,如int64/object |
维度信息 | df.shape | 元组形式(行数, 列数) |
快速统计 | df.describe() | 自动计算计数 / 均值 / 标准差等 |
三、数据输入输出全场景
3.1 数据读取高级用法
3.1.1 CSV 读取参数详解
df = pd.read_csv(
'data/products_sales.csv',
sep=';', # 字段分隔符,默认逗号
encoding='utf-8', # 字符编码
nrows=1000, # 读取前1000行
skiprows=[2, 5], # 跳过第3行和第6行
index_col='id' # 指定行索引列
)
3.1.2 网络数据读取
# 直接读取URL数据
df_web = pd.read_csv('https://www.gairuo.com/file/data/dataset/GDP-China.csv')
3.2 数据保存与格式转换
3.2.1 CSV 保存(去索引)
# 不保存索引列,适用于纯数据导出
df.to_csv('data/清洗后数据.csv', index=False)
3.2.2 Excel 多表保存
with pd.ExcelWriter('data/汇总数据.xlsx') as writer:
df1.to_excel(writer, sheet_name='销售表')
df2.to_excel(writer, sheet_name='库存表')
四、数据基础处理操作
4.1 数据筛选与选择
4.1.1 基础筛选语法
df = pd.DataFrame({
'日期': ['2023-01-01', '2023-01-02'],
'公司': ['BIDU', 'JD'],
'价格': [103.85, 28.06]
})
# 按列名选择
print(df['公司']) # 输出Series:0 BIDU\n1 JD\nName: 公司, dtype: object
# 按标签选行
print(df.loc[0]) # 输出第1行数据
# 按位置选行
print(df.iloc[1]) # 输出第2行数据(索引从0开始)
# 条件筛选
print(df[df['价格'] > 50]) # 输出BIDU相关行
4.2 排序操作详解
4.2.1 单列排序
# 按价格降序排列
df_sort = df.sort_values(by='价格', ascending=False)
输出结果
日期 公司 价格
0 2023-01-01 BIDU 103.85
1 2023-01-02 JD 28.06
4.2.2 索引排序
# 按行索引降序排列
df_idx_sort = df.sort_index(ascending=False)
输出结果
日期 公司 价格
1 2023-01-02 JD 28.06
0 2023-01-01 BIDU 103.85
4.3 统计计算与描述分析
4.3.1 描述性统计
df_stat = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6]
})
print(df_stat.describe())
输出结果
A B
count 3.000000 3.000000
mean 2.000000 5.000000
std 1.000000 1.000000
min 1.000000 4.000000
25% 1.500000 4.500000
50% 2.000000 5.000000
75% 2.500000 5.500000
max 3.000000 6.000000
4.3.2 协方差与相关系数
# 协方差矩阵
print(df_stat.cov())
输出结果
A B
A 1.000000 1.000000
B 1.000000 1.000000
# 相关系数矩阵
print(df_stat.corr())
输出结果
A B
A 1.000000 1.000000
B 1.000000 1.000000
五、高级数据处理技术
5.1 缺失值处理全流程
5.1.1 缺失值检测
# 创建带缺失值数据
df_missing = pd.DataFrame({
'A': [1, np.nan, 3],
'B': [np.nan, 5, 6]
})
# 布尔矩阵检测
print(df_missing.isnull())
输出结果
A B
0 False True
1 True False
2 False False
5.1.2 缺失值填充
# 均值填充
df_fill = df_missing.fillna(df_missing.mean())
输出结果
A B
0 1.0 5.5
1 2.0 5.0
2 3.0 6.0
5.1.3 缺失值删除
# 删除包含缺失值的行
df_drop = df_missing.dropna()
输出结果
A B
2 3 6
5.2 数据分组与聚合分析
5.2.1 单变量分组
df_group = pd.DataFrame({
'性别': ['男', '女', '男', '女'],
'年龄': [22, 18, 25, 20],
'身高': [180, 160, 175, 165]
})
# 按性别分组求均值
group_result = df_group.groupby('性别').mean()
输出结果
年龄 身高
性别
女 19.0 162.5
男 23.5 177.5
5.2.2 多变量分组
# 按性别和年龄分组求和
multi_group = df_group.groupby(['性别', '年龄']).sum()
输出结果
身高
性别 年龄
女 18 160
20 165
男 22 180
25 175
5.3 数据合并技术对比
5.3.1 concat 纵向合并
# 创建待合并数据
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
# 纵向合并(默认axis=0)
concat_result = pd.concat([df1, df2])
输出结果
A B
0 1 3
1 2 4
0 5 7
1 6 8
5.3.2 merge 关联合并
# 产品表与销售表合并
df_product = pd.DataFrame({
'id': [1, 2, 3],
'name': ['A', 'B', 'C']
})
df_sales = pd.DataFrame({
'id': [1, 3, 4],
'qty': [10, 20, 15]
})
# 左连接合并
merge_result = pd.merge(df_product, df_sales, on='id', how='left')
输出结果
id name qty
0 1 A 10.0
1 2 B NaN
2 3 C 20.0
六、透视表与交叉表高级应用
6.1 透视表深度解析
6.1.1 基础透视表
df_sales = pd.DataFrame({
'地区': ['北京', '北京', '上海', '上海'],
'产品': ['A', 'B', 'A', 'B'],
'销售额': [100, 150, 200, 180]
})
# 按地区和产品分组汇总销售额
pivot_table = pd.pivot_table(
df_sales,
index='地区',
columns='产品',
values='销售额',
aggfunc='sum'
)
输出结果
产品 A B
地区
北京 100 150
上海 200 180
6.1.2 多指标透视表
# 同时计算销售额总和与销量均值
pivot_multi = pd.pivot_table(
df_sales,
index='地区',
columns='产品',
values=['销售额', '销量'],
aggfunc={'销售额': 'sum', '销量': 'mean'}
)
6.2 交叉表统计分析
6.2.1 基础交叉表
# 统计地区与产品的交叉频数
cross_table = pd.crosstab(df_sales['地区'], df_sales['产品'])
输出结果
产品 A B
地区
北京 1 1
上海 1 1
6.2.2 聚合交叉表
# 统计各地区各产品的销售额总和
agg_cross = pd.crosstab(
df_sales['地区'],
df_sales['产品'],
values=df_sales['销售额'],
aggfunc='sum'
)
输出结果
产品 A B
地区
北京 100 150
上海 200 180
七、实战案例:学生成绩分析
7.1 数据准备
# 创建学生成绩数据
score_data = {
'姓名': ['张三', '李四', '王五', '赵六', '郑七'],
'课程一': [85, 90, 78, 92, 88],
'课程二': [76, 87, 85, 79, 91],
'课程三': [92, 81, 88, 76, 95],
'课程四': [88, 78, 93, 86, 82]
}
df_score = pd.DataFrame(score_data)
df_score.set_index('姓名', inplace=True) # 设置姓名为索引
数据结构
课程一 课程二 课程三 课程四
姓名
张三 85 76 92 88
李四 90 87 81 78
王五 78 85 88 93
赵六 92 79 76 86
郑七 88 91 95 82
7.2 数据分析操作
7.2.1 单条数据提取
# 提取李四的课程三成绩
li_si_course3 = df_score.loc['李四', '课程三'] # 输出:81
7.2.2 分组统计
# 计算各课程平均分
course_mean = df_score.mean()
输出结果
课程一 86.6
课程二 83.2
课程三 86.4
课程四 85.8
dtype: float64
7.2.3 条件筛选
# 筛选课程三成绩>80分的学生
high_course3 = df_score[df_score['课程三'] > 80]
输出结果
课程一 课程二 课程三 课程四
姓名
张三 85 76 92 88
李四 90 87 81 78
王五 78 85 88 93
郑七 88 91 95 82
八、常见问题与技巧集锦
8.1 数据类型转换技巧
8.1.1 字符串转数值
# 转换并将无效值转为NaN
df['price'] = pd.to_numeric(df['price'], errors='coerce')
8.1.2 字符串转日期
# 自动识别多种日期格式
df['date'] = pd.to_datetime(df['date_str'])
8.2 数据清洗实用技巧
8.2.1 去重处理
# 删除完全重复的行
df_duplicated = df.drop_duplicates()
# 按指定列去重
df_col_duplicated = df.drop_duplicates(subset=['id'])
8.2.2 异常值替换
# 将-999替换为NaN
df_replace = df.replace(-999, np.nan)
# 批量替换多个值
df_multi_replace = df.replace([0, -1], np.nan)