Python pandas 数据分析入门与实战
Python pandas 是 Python 数据分析核心库,提供 Series 和 DataFrame 结构。内容涵盖安装导入、数据读写、清洗(缺失值/重复值)、筛选分组聚合及排序。包含实战案例分析用户数据,并总结乱码、内存不足及 SettingWithCopyWarning 等常见问题处理。适合数据分析初学者快速上手。

Python pandas 是 Python 数据分析核心库,提供 Series 和 DataFrame 结构。内容涵盖安装导入、数据读写、清洗(缺失值/重复值)、筛选分组聚合及排序。包含实战案例分析用户数据,并总结乱码、内存不足及 SettingWithCopyWarning 等常见问题处理。适合数据分析初学者快速上手。

pandas 是 Python 的一个开源数据分析库,诞生于 2008 年,名字来源于'Panel Data'(面板数据)。它基于 NumPy 构建,提供了两种核心数据结构(Series 和 DataFrame),以及一系列便捷的函数,能轻松处理表格型数据。
pandas 不是 Python 标准库,需用 pip 安装(建议同时安装依赖库 openpyxl,用于处理 Excel 文件):
# 基础安装(支持 CSV、文本等)
pip install pandas
# 完整安装(支持 Excel、数据库等)
pip install pandas openpyxl
惯例将 pandas 简写为 pd(行业通用约定):
import pandas as pd
pandas 的所有操作都围绕两种核心结构展开:Series(一维数组) 和 DataFrame(二维表格)。
Series 类似 Python 列表,但每个元素都有一个'标签'(索引,index)。
# 方式 1:从列表创建(默认索引为 0,1,2...)
s1 = pd.Series([10, 20, 30, 40])
print("s1:\n", s1)
# 方式 2:指定索引(标签)
s2 = pd.Series([10, 20, 30], index=["a", "b", "c"])
print("\ns2:\n", s2)
# 方式 3:从字典创建(键为索引,值为数据)
s3 = pd.Series({"北京": 2000, "上海": 2500, "广州": 1800})
print("\ns3:\n", s3)
s = pd.Series([10, 20, 30, 40], index=["a", "b", "c", "d"])
# 通过索引(标签)访问
print(s["b"]) # 输出:20
# 通过位置访问(类似列表)
print(s[1]) # 输出:20
# 切片访问(包含端点)
print(s["b":"d"]) # 输出索引"b"到"d"的元素
DataFrame 是 pandas 中最常用的结构,类似 Excel 表格或数据库表。
# 方式 1:从字典列表创建(每个字典是一行)
data = [{"name": "张三", "age": 25, "city": "北京"}, {"name": "李四", "age": 22, "city": "上海"}]
df1 = pd.DataFrame(data)
print("df1:\n", df1)
# 方式 2:从字典创建(键为列名,值为列数据)
data = {"name": ["张三", "李四"], "age": [25, 22], "city": ["北京", "上海"]}
df2 = pd.DataFrame(data, index=["u1", "u2"])
print("\ndf2:\n", df2)
df = pd.DataFrame({"name": ["张三", "李四"], "age": [25, 22], "city": ["北京", "上海"]})
print("形状(行,列):", df.shape)
print("列名:", df.columns)
print("行索引:", df.index)
print("数据类型:\n", df.dtypes)
pandas 支持读取/写入多种文件格式(CSV、Excel、JSON、SQL 等)。
# 读取 CSV(默认逗号分隔,自动识别表头)
df = pd.read_csv("data.csv", encoding="utf-8")
# 读取无表头的 CSV(指定 header=None,手动设置列名)
df = pd.read_csv("no_header.csv", header=None, names=["col1", "col2", "col3"])
# 读取 Excel 的第一个工作表(sheet_name 默认 0)
df = pd.read_excel("data.xlsx", sheet_name="用户数据", engine="openpyxl")
df = pd.read_json("data.json", encoding="utf-8")
df.to_csv("output.csv", index=False, encoding="utf-8")
# 写入 Excel,指定工作表名
df.to_excel("output.xlsx", sheet_name="结果数据", index=False, engine="openpyxl")
df = pd.read_csv("user_data.csv")
# 查看前 5 行(默认),适合快速预览
print("前 5 行:\n", df.head())
# 查看后 3 行
print("\n后 3 行:\n", df.tail(3))
# 查看数据基本统计信息(仅对数值列有效)
print("\n统计信息:\n", df.describe())
# 查看数据类型、非空值数量
print("\n数据信息:")
df.info()
df = pd.DataFrame({"name": ["张三", "李四"], "age": [25, 22], "city": ["北京", "上海"], "salary": [15000, 12000]})
# 选择单列(返回 Series)
print("年龄列:\n", df["age"])
# 选择多列(返回 DataFrame,传入列名列表)
print("\n姓名和薪资:\n", df[["name", "salary"]])
# 条件 1:年龄>24
cond1 = df["age"] > 24
print("年龄>24 的用户:\n", df[cond1])
# 条件 2:薪资>13000 且城市是北京
cond2 = (df["salary"] > 13000) & (df["city"] == "北京")
print("\n薪资>13000 且北京的用户:\n", df[cond2])
# 条件 3:城市是上海或广州(用 isin)
cond3 = df["city"].isin(["上海", "广州"])
print("\n城市是上海或广州的用户:\n", df[cond3])
# 取第 0 行(第一行)
print("第 0 行:\n", df.iloc[0])
# 取第 1 到 2 行(左闭右开)
print("\n第 1-2 行:\n", df.iloc[1:3])
# 取第 0 行第 1 列
print("\n第 0 行第 1 列:", df.iloc[0, 1])
# 取多行多列
print("\n多行多列:\n", df.iloc[0:2, 0:3])
# 重置行索引为 name 列(方便按姓名筛选)
df = df.set_index("name")
# 取行标签为"李四"的行
print("李四的信息:\n", df.loc["李四"])
# 取行标签"张三"到"王五",列标签"age"到"salary"
print("\n指定行列范围:\n", df.loc["张三":"王五", "age":"salary"])
# 创建含缺失值的 DataFrame
df = pd.DataFrame({"name": ["张三", "李四", None, "王五"], "age": [25, None, 30, 35], "city": ["北京", "上海", None, "广州"]})
print("原始数据:\n", df)
# (1)查看缺失值(每列的缺失值数量)
print("\n缺失值数量:\n", df.isnull().sum())
# (2)删除缺失值(行)
df_drop = df.dropna()
print("\n删除缺失值后的行:\n", df_drop)
# (3)填充缺失值(常用)
df_fill = df.copy()
# 数值列用均值填充(如 age)
df_fill["age"] = df_fill["age"].fillna(df_fill["age"].mean())
# 字符串列用默认值填充(如 name 和 city)
df_fill["name"] = df_fill["name"].fillna("未知")
df_fill["city"] = df_fill["city"].fillna("未知城市")
print("\n填充缺失值后:\n", df_fill)
# 创建含重复行的 DataFrame
df = pd.DataFrame({"name": ["张三", "李四", "张三", "王五"], "age": [25, 22, 25, 30], "city": ["北京", "上海", "北京", "广州"]})
print("原始数据:\n", df)
# (1)检测重复行(完全相同的行)
print("\n重复行标记:\n", df.duplicated())
# (2)删除重复行
df_unique = df.drop_duplicates()
print("\n删除重复行后:\n", df_unique)
# (3)按指定列检测重复(如 name 列)
df_unique_name = df.drop_duplicates(subset=["name"])
print("\n按 name 去重后:\n", df_unique_name)
df = pd.DataFrame({"name": ["张三", "李四", "王五"], "age": [25, 22, 30], "salary": [15000, 12000, 18000]})
# (1)新增列(基于现有列计算)
df["annual_salary"] = df["salary"] * 12
print("新增年薪列:\n", df)
# (2)修改列(条件赋值)
# 给 30 岁以上的用户薪资加 1000
df.loc[df["age"] > 28, "salary"] += 1000
print("\n修改后薪资:\n", df)
# (3)删除列
df_drop_col = df.drop(columns=["annual_salary"])
print("\n删除列后:\n", df_drop_col)
df = pd.DataFrame({"name": ["张三", "李四", "王五"], "age": [25, 22, 30], "salary": [15000, 12000, 18000]})
# (1)按单列排序(升序)
df_sorted_age = df.sort_values(by="age")
print("按年龄升序:\n", df_sorted_age)
# (2)按多列排序(先按 age 降序,再按 salary 升序)
df_sorted_multi = df.sort_values(by=["age", "salary"], ascending=[False, True])
print("\n多列排序:\n", df_sorted_multi)
分组聚合(groupby)是数据分析的核心操作。
df = pd.DataFrame({"name": ["张三", "李四", "王五", "赵六", "孙七"], "city": ["北京", "北京", "上海", "上海", "北京"], "age": [25, 30, 22, 28, 35], "salary": [15000, 18000, 12000, 16000, 20000]})
# (1)按城市分组(返回 GroupBy 对象)
group_city = df.groupby("city")
# (2)对分组后的数值列计算统计量
agg_result = group_city.agg({"age": "mean", "salary": "sum"})
print("分组聚合结果:\n", agg_result)
# (3)常用聚合函数:mean(均值)、sum(总和)、count(数量)、max(最大值)、min(最小值)
print("\n每个城市的人数:\n", group_city.size())
用一个完整案例串联前面的知识点:分析用户数据(CSV 文件)。
import pandas as pd
# 1. 读取数据
df = pd.read_csv("user_data.csv", encoding="utf-8")
print("原始数据形状:", df.shape)
print("前 3 行数据:\n", df.head(3))
# 2. 数据清洗
# (1)处理缺失值
print("\n缺失值数量:\n", df.isnull().sum())
df["age"] = df["age"].fillna(df["age"].mean())
df["city"] = df["city"].fillna("未知城市")
# (2)处理重复值
df = df.drop_duplicates(subset=["user_id"])
print("\n去重后数据形状:", df.shape)
# 3. 数据分析
# (1)各城市用户数量
city_count = df["city"].value_counts()
print("\n各城市用户数量:\n", city_count)
# (2)按城市分组,计算平均年龄和平均薪资
city_agg = df.groupby("city").agg({"age": "mean", "salary": "mean"}).round(2)
print("\n各城市平均年龄和薪资:\n", city_agg)
# 4. 筛选高收入用户并保存
high_income = df[df["salary"] > 15000]
high_income.to_csv("high_income_users.csv", index=False, encoding="utf-8")
print(f"\n高收入用户(薪资>15000)共{len(high_income)}人,已保存到文件。")
问题:读取/写入文件时中文显示乱码。
解决:读取和写入时指定 encoding="utf-8" 或 encoding="gbk":
df = pd.read_csv("data.csv", encoding="utf-8")
df.to_csv("output.csv", encoding="utf-8", index=False)
问题:修改 DataFrame 子集时出现警告。
原因:pandas 无法确定你是否在修改副本还是原数据。
解决:用 loc 一次性完成筛选和修改:
# 正确写法
df.loc[df["age"] > 30, "salary"] += 1000
问题:读取百万级以上行数据时,内存占用过高。 解决:
dtype 指定列的数据类型(如将 int64 改为 int32,object 改为 category 节省内存);pd.read_csv("big_data.csv", chunksize=10000)。问题:日期列被识别为字符串(object 类型)。
解决:读取时用 parse_dates 指定日期列,或用 pd.to_datetime() 转换:
# 读取时解析日期
df = pd.read_csv("data.csv", parse_dates=["birth_date"])
# 后续转换
df["birth_date"] = pd.to_datetime(df["birth_date"], format="%Y-%m-%d")
pandas 的核心价值在于 '用简洁的代码实现复杂的数据处理'。
df.+Tab 键查看可用方法,提高效率。掌握 pandas 后,你会发现数据分析不再是'体力活',而是'用代码快速验证想法'的过程。无论是数据分析师、算法工程师还是后端开发,pandas 都是必备技能。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online