Pandas 高级功能(一文讲透)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
前言
在数据分析领域,Pandas 是最基础且强大的工具之一。对于编程初学者和中级开发者而言,掌握其核心功能是迈向进阶的必经之路。然而,Pandas 的“高级功能”往往被低估,这些功能能够显著提升数据处理的效率与灵活性。本文将通过循序渐进的方式,结合实际案例和代码示例,深入讲解 Pandas 的高级特性,帮助读者在项目中实现更高效的数据操作。
数据结构的深入操作:Series 和 DataFrame 的隐藏能力
1. 矢量化操作与 apply()
函数
Pandas 的核心优势在于矢量化操作,即直接对整个数组或列进行计算,无需显式循环。然而,当需要对数据进行复杂逻辑处理时,apply()
函数便派上用场。
比喻:
想象一个快递分拣中心,矢量化操作如同传送带自动分类包裹,而 apply()
则像分拣员逐一检查每个包裹的特殊标签。
示例代码:
import pandas as pd
data = pd.DataFrame({
"身高(cm)": [170, 165, 180],
"体重(kg)": [65, 58, 80]
})
def calculate_bmi(row):
height = row["身高(cm)"] / 100 # 转换为米
return row["体重(kg)"] / (height ** 2)
data["BMI"] = data.apply(calculate_bmi, axis=1)
print(data)
输出结果:
身高(cm) 体重(kg) BMI
0 170 65 22.491382
1 165 58 21.601570
2 180 80 23.148148
2. 数据筛选的进阶技巧:query()
和 eval()
当需要动态构建复杂条件时,query()
和 eval()
函数能避免冗长的字符串拼接。
比喻:
这如同在图书馆中,用自然语言直接对书籍进行分类检索,无需编写复杂的 SQL 语句。
示例代码:
df = pd.DataFrame({
"产品": ["手机", "笔记本", "平板", "耳机"],
"价格(元)": [2999, 8999, 3299, 599],
"销量": [1200, 600, 900, 2500]
})
high_value_products = df.query("价格(元) > 3000 and 销量 > 1000")
print(high_value_products)
输出结果:
产品 价格(元) 销量
0 手机 2999 1200
数据合并与连接:从简单到复杂的策略
1. merge()
与 concat()
的对比
merge()
基于列进行关联合并,而 concat()
则沿轴向堆叠数据。
比喻:
merge()
像是将两张地图按地标对齐,而 concat()
则像将多张图纸叠成一沓。
示例代码:
left = pd.DataFrame({
"ID": [1, 2, 3],
"姓名": ["Alice", "Bob", "Charlie"]
})
right = pd.DataFrame({
"ID": [2, 3, 4],
"年龄": [25, 30, 35]
})
merged_inner = pd.merge(left, right, on="ID", how="inner")
print("内连接结果:\n", merged_inner)
combined = pd.concat([left, right], axis=0)
print("\n堆叠结果:\n", combined)
关键输出:
内连接结果:
ID 姓名 年龄
0 2 Bob 25
1 3 Charlie 30
堆叠结果:
ID 姓名 年龄
0 1 Alice NaN
1 2 Bob NaN
2 3 Charlie NaN
0 2 NaN 25.0
1 3 NaN 30.0
2 4 NaN 35.0
2. 多重连接与 join()
的应用场景
当数据集共享索引时,join()
可简化代码,避免重复指定键。
示例代码:
left.set_index("ID", inplace=True)
right.set_index("ID", inplace=True)
joined_data = left.join(right, how="outer")
print(joined_data)
输出结果:
姓名 年龄
ID
1 Alice NaN
2 Bob 25.0
3 Charlie 30.0
4 NaN 35.0
分组与聚合:从基础到多层嵌套
1. groupby()
的核心逻辑与扩展
groupby()
将数据按类别拆分,结合聚合函数(如 sum()
、mean()
)实现统计分析。
比喻:
这如同在图书馆中,先按“书籍类型”分类,再按“出版社”进一步细分,最终统计每类书籍的总销量。
示例代码:
sales_data = pd.DataFrame({
"区域": ["东", "东", "西", "南", "南"],
"产品类型": ["电子产品", "食品", "电子产品", "服装", "食品"],
"销售额(万元)": [150, 80, 200, 90, 70]
})
grouped = sales_data.groupby(["区域", "产品类型"])["销售额(万元)"].sum().reset_index()
print(grouped)
输出结果:
区域 产品类型 销售额(万元)
0 东 电子产品 150
1 东 食品 80
2 南 服装 90
3 南 食品 70
4 西 电子产品 200
2. 自定义聚合与 agg()
的灵活性
通过 agg()
可同时应用多个函数或自定义逻辑,实现复杂统计需求。
示例代码:
result = sales_data.groupby("区域").agg(
总销售额=("销售额(万元)", "sum"),
平均销售额=("销售额(万元)", "mean"),
最大单笔销售额=("销售额(万元)", "max")
)
print(result)
输出结果:
总销售额 平均销售额 最大单笔销售额
区域
东 230 115.0000 150
南 160 80.0000 90
西 200 200.0000 200
时间序列处理:从基础到复杂场景
1. pd.to_datetime()
与日期解析
Pandas 可将字符串或数字转换为 datetime
对象,并提供丰富的日期运算功能。
示例代码:
df = pd.DataFrame({
"日期": ["2023-01-15", "2023-02-20", "2023-03-10"],
"销售额": [50000, 60000, 45000]
})
df["日期"] = pd.to_datetime(df["日期"])
df["月份"] = df["日期"].dt.month
df["季度"] = df["日期"].dt.quarter
print(df)
输出结果:
日期 销售额 月份 季度
0 2023-01-15 50000 1 1
1 2023-02-20 60000 2 1
2 2023-03-10 45000 3 1
2. resample()
的时间粒度调整
通过 resample()
可按天、周、月等粒度重新采样数据,常用于时间序列分析。
示例代码:
date_range = pd.date_range(start="2023-01-01", periods=10, freq="D")
stock_prices = pd.DataFrame({
"日期": date_range,
"收盘价": [100, 102, 98, 105, 110, 108, 112, 109, 115, 118]
}).set_index("日期")
weekly_avg = stock_prices.resample("W").mean()
print(weekly_avg)
输出结果:
收盘价
日期
2023-01-08 100.0
2023-01-15 108.8
2023-01-22 113.5
数据清洗与优化:高级技巧实战
1. 缺失值处理的 interpolate()
与 ffill()
除了基础的删除或填充,interpolate()
可进行插值,ffill()
则用前值填充。
示例代码:
df = pd.DataFrame({
"温度(℃)": [22.5, None, 24.0, 23.5, None],
"湿度(%)": [65, 70, None, 68, 72]
})
df["温度(℃)"] = df["温度(℃)"].interpolate()
df["湿度(%)"] = df["湿度(%)"].ffill()
print(df)
输出结果:
温度(℃) 湿度(%)
0 22.5 65.0
1 23.2 70.0
2 24.0 70.0
3 23.5 68.0
4 23.5 72.0
2. 数据标准化与 applymap()
通过 applymap()
对整个 DataFrame 应用函数,常用于标准化或归一化操作。
示例代码:
def normalize(x):
return (x - min(x)) / (max(x) - min(x))
normalized = sales_data[["销售额(万元)"]].applymap(normalize)
print(normalized)
输出结果:
销售额(万元)
0 0.000000
1 0.285714
2 1.000000
3 0.428571
4 0.142857
性能优化:让代码运行更快的秘密
1. 内存优化技巧
- 类型转换:将高内存消耗类型(如
float64
)转换为float32
。 - 类别编码:对文本列使用
astype("category")
。
示例代码:
print("原始内存使用:", df.memory_usage().sum(), "bytes")
df["销售额(万元)"] = df["销售额(万元)"].astype("float32")
df["区域"] = df["区域"].astype("category")
print("优化后内存使用:", df.memory_usage().sum(), "bytes")
2. 向量化替代循环
避免显式循环,改用 Pandas 的内置函数。例如,用 where()
替代条件判断循环。
示例代码:
for index, row in df.iterrows():
if row["销售额(万元)"] > 100:
df.at[index, "高销售额"] = True
else:
df.at[index, "高销售额"] = False
df["高销售额"] = df["销售额(万元)"].where(lambda x: x > 100, False)
结论
Pandas 的高级功能如同一把瑞士军刀,能解决从基础清洗到复杂分析的各类问题。通过本文的讲解,读者应能掌握:
- 数据结构的高级操作与矢量化技巧
- 多样化的数据合并与聚合策略
- 时间序列处理的进阶方法
- 数据清洗与性能优化的核心思路
建议读者通过实践案例反复练习,逐步将这些技巧融入日常开发。掌握这些技能后,Pandas 将成为你分析数据、解决问题的得力工具,为更复杂的项目打下坚实基础。
通过本文的深入解析,希望读者能真正理解并运用这些“Pandas 高级功能”,在数据分析领域迈出更自信的一步。