第4章 数据科学三剑客:NumPy基础、Pandas数据处理、Matplotlib数据可视化入门
说实话,刚入行那会儿,我总觉得数据科学离自己很远。直到第一次接手一个用户行为分析项目,面对几十万行CSV文件,Excel直接卡死,我才意识到——嗯,Python的数据科学三剑客,是绕不过去的坎。
这三样东西,说白了就是:NumPy管计算、Pandas管表格、Matplotlib管画图。今天咱们就一个一个来过一遍。
4.1 NumPy基础:高性能数组计算
NumPy,全称是Numerical Python。它最核心的东西就是ndarray,也就是N维数组对象。我习惯叫它“张量”,虽然严格来说不太一样,但意思差不多。
4.1.1 创建数组
创建数组的方式有很多,我挑几个最常用的说说。
import numpy as np
# 从列表创建
arr1 = np.array([1, 2, 3, 4, 5])
# 全零数组
arr2 = np.zeros((3, 4))
# 全一数组
arr3 = np.ones((2, 3))
# 等差数列
arr4 = np.arange(0, 10, 2) # [0, 2, 4, 6, 8]
# 均匀分布
arr5 = np.linspace(0, 1, 5) # [0. , 0.25, 0.5, 0.75, 1. ]
np.random.randn()生成正态分布数据。比如模拟用户年龄分布,用它特别方便。
4.1.2 数组运算
NumPy的向量化运算,是它最大的亮点。你想想看,如果用Python原生列表做加法,得写个for循环。但NumPy直接一行搞定。
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 对应元素相加
c = a + b # [5, 7, 9]
# 标量运算
d = a * 2 # [2, 4, 6]
# 矩阵乘法
e = a.dot(b) # 32
为什么会这么快?因为底层是C语言实现的,而且利用了CPU的SIMD指令集。我在项目中遇到过一个问题:用Python列表处理100万条数据,跑了快10秒;换成NumPy,0.1秒就搞定了。差距就是这么大。
4.1.3 索引与切片
NumPy的索引和Python列表类似,但多了个“花式索引”的概念。
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 普通索引
print(arr[0, 1]) # 2
# 切片
print(arr[:2, 1:]) # [[2, 3], [5, 6]]
# 花式索引
indices = [0, 2]
print(arr[indices]) # [[1, 2, 3], [7, 8, 9]]
.copy()。
4.2 Pandas数据处理:表格操作的瑞士军刀
Pandas,我个人觉得它是Python数据分析的灵魂。它的两个核心数据结构:Series(一维)和DataFrame(二维)。
4.2.1 创建DataFrame
实际项目中,数据大多从文件读取。但为了演示,咱们先手动创建一个。
import pandas as pd
data = {
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 30, 28],
'城市': ['北京', '上海', '广州']
}
df = pd.DataFrame(data)
print(df)
输出结果:
| 姓名 | 年龄 | 城市 |
|---|---|---|
| 张三 | 25 | 北京 |
| 李四 | 30 | 上海 |
| 王五 | 28 | 广州 |
4.2.2 数据读取与写入
这是最常用的功能。我建议你记住这几个函数:
pd.read_csv()— 读取CSV文件pd.read_excel()— 读取Excel文件pd.read_json()— 读取JSON文件df.to_csv()— 保存为CSV
# 读取CSV
df = pd.read_csv('user_data.csv', encoding='utf-8')
# 查看前5行
print(df.head())
# 查看基本信息
print(df.info())
# 查看统计摘要
print(df.describe())
encoding='utf-8-sig',完美解决。另外,大文件读取时记得加chunksize参数,不然内存容易爆。
4.2.3 数据清洗
真实数据,永远不干净。我总结了一套“清洗三板斧”:
- 处理缺失值:
df.dropna()或df.fillna() - 处理重复值:
df.drop_duplicates() - 处理异常值:结合条件筛选
# 查看缺失值
print(df.isnull().sum())
# 填充缺失值
df['年龄'].fillna(df['年龄'].mean(), inplace=True)
# 删除重复行
df.drop_duplicates(inplace=True)
# 筛选年龄在0-120之间的数据
df = df[(df['年龄'] > 0) & (df['年龄'] < 120)]
4.2.4 分组与聚合
分组聚合是数据分析的核心操作。我经常用它来做用户分层分析。
# 按城市分组,计算平均年龄
result = df.groupby('城市')['年龄'].mean()
# 多维度聚合
result = df.groupby('城市').agg({
'年龄': ['mean', 'max', 'min'],
'姓名': 'count'
})
4.3 Matplotlib数据可视化入门
数据可视化,说白了就是“一图胜千言”。Matplotlib是Python最经典的绘图库,虽然现在有很多新库(比如Seaborn、Plotly),但Matplotlib依然是基础。
4.3.1 基本绘图流程
我习惯用pyplot模块,它模仿了MATLAB的绘图风格。
import matplotlib.pyplot as plt
# 准备数据
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]
# 创建画布
plt.figure(figsize=(8, 5))
# 绘制折线图
plt.plot(x, y, marker='o', linestyle='-', color='b')
# 添加标签和标题
plt.xlabel('X轴')
plt.ylabel('Y轴')
plt.title('折线图示例')
# 显示网格
plt.grid(True)
# 显示图形
plt.show()
4.3.2 常用图表类型
我整理了一个表格,方便你快速查阅:
| 图表类型 | 函数 | 适用场景 |
|---|---|---|
| 折线图 | plt.plot() | 趋势变化 |
| 柱状图 | plt.bar() | 类别对比 |
| 散点图 | plt.scatter() | 相关性分析 |
| 直方图 | plt.hist() | 数据分布 |
| 饼图 | plt.pie() | 占比展示 |
# 柱状图示例
categories = ['A', 'B', 'C', 'D']
values = [23, 45, 56, 78]
plt.bar(categories, values, color=['red', 'blue', 'green', 'orange'])
plt.title('柱状图示例')
plt.show()
# 散点图示例
import numpy as np
x = np.random.randn(100)
y = np.random.randn(100)
plt.scatter(x, y, alpha=0.6)
plt.title('散点图示例')
plt.show()
4.3.3 子图与布局
有时候需要在一张图里展示多个图表。我常用subplots来实现。
# 创建2行2列的子图
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
# 在第一个子图绘制
axes[0, 0].plot([1, 2, 3], [1, 4, 9])
axes[0, 0].set_title('子图1')
# 在第二个子图绘制
axes[0, 1].bar(['A', 'B'], [3, 7])
axes[0, 1].set_title('子图2')
# 调整布局
plt.tight_layout()
plt.show()
plt.cm里的配色方案,比自己瞎选好看多了。
4.4 三剑客协同实战
最后,咱们来个综合案例。假设我们要分析一份销售数据:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 1. 生成模拟数据
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=100, freq='D')
sales = np.random.randint(100, 500, size=100)
cities = np.random.choice(['北京', '上海', '广州', '深圳'], size=100)
df = pd.DataFrame({
'日期': dates,
'销售额': sales,
'城市': cities
})
# 2. 数据清洗
df.dropna(inplace=True)
# 3. 数据分析:按城市统计
city_stats = df.groupby('城市')['销售额'].agg(['mean', 'sum', 'count'])
print(city_stats)
# 4. 数据可视化
plt.figure(figsize=(12, 5))
# 折线图:每日销售额趋势
plt.subplot(1, 2, 1)
plt.plot(df['日期'], df['销售额'], alpha=0.7)
plt.title('每日销售额趋势')
plt.xticks(rotation=45)
# 柱状图:各城市销售额对比
plt.subplot(1, 2, 2)
city_stats['sum'].plot(kind='bar', color=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4'])
plt.title('各城市总销售额')
plt.ylabel('销售额')
plt.tight_layout()
plt.show()
你看,从数据生成、清洗、分析到可视化,三剑客配合得天衣无缝。我个人觉得,掌握了这三样东西,你就已经具备了处理80%数据分析场景的能力。
嗯,今天就先聊到这儿。下一章咱们会深入讲讲数据预处理的高级技巧,包括特征工程和文本数据清洗。到时候见。