Python 编程教程 / 19 - 数据科学
第 19 章:数据科学
掌握 NumPy、Pandas、Matplotlib 和 Jupyter 进行数据处理与分析。
19.1 Jupyter Notebook
19.1.1 使用 Jupyter
# 安装
$ pip install jupyterlab
# 启动
$ jupyter lab
# 浏览器打开 http://localhost:8888
# 或使用 VS Code 的 Jupyter 扩展
Jupyter 支持交互式编程,混合代码、文本、图表,非常适合数据分析和探索。
19.1.2 Jupyter 基本操作
| 快捷键 | 功能 |
|---|---|
Shift+Enter | 运行当前单元格 |
Esc+A | 上方插入单元格 |
Esc+B | 下方插入单元格 |
Esc+M | 转为 Markdown |
Esc+DD | 删除单元格 |
19.2 NumPy
19.2.1 数组创建
import numpy as np
# 从列表创建
arr = np.array([1, 2, 3, 4, 5])
print(type(arr)) # <class 'numpy.ndarray'>
# 常用创建方法
np.zeros(5) # [0. 0. 0. 0. 0.]
np.ones((3, 4)) # 3x4 全1矩阵
np.arange(0, 10, 2) # [0, 2, 4, 6, 8]
np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1. ]
np.random.rand(3, 3) # 3x3 随机矩阵
np.eye(3) # 3x3 单位矩阵
19.2.2 数组操作
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape) # (2, 3)
print(arr.ndim) # 2
print(arr.size) # 6
print(arr.dtype) # int64
# 索引和切片
print(arr[0, 1]) # 2
print(arr[:, 0]) # [1, 4] 第一列
print(arr[1, :]) # [4, 5, 6] 第二行
# 变形
arr.reshape(3, 2) # 变形
arr.flatten() # 展平
# 转置
arr.T # 转置
19.2.3 数学运算
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 逐元素运算
print(a + b) # [5, 7, 9]
print(a * b) # [4, 10, 18]
print(a ** 2) # [1, 4, 9]
# 聚合
print(np.sum(a)) # 6
print(np.mean(a)) # 2.0
print(np.std(a)) # 标准差
print(np.max(a)) # 3
print(np.dot(a, b)) # 点积: 32
# 矩阵运算
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(A @ B) # 矩阵乘法
print(np.linalg.inv(A)) # 逆矩阵
19.2.4 广播(Broadcasting)
# 形状不同的数组也能运算
arr = np.array([[1, 2, 3], [4, 5, 6]]) # (2, 3)
scalar = 10
print(arr + scalar) # 每个元素加 10
row = np.array([10, 20, 30]) # (3,)
print(arr + row) # 每行加 row
19.3 Pandas
19.3.1 DataFrame 基础
import pandas as pd
# 创建 DataFrame
data = {
"name": ["Alice", "Bob", "Charlie"],
"age": [30, 25, 35],
"city": ["北京", "上海", "广州"],
}
df = pd.DataFrame(data)
print(df)
# name age city
# 0 Alice 30 北京
# 1 Bob 25 上海
# 2 Charlie 35 广州
# 基本信息
print(df.shape) # (3, 3)
print(df.dtypes) # 数据类型
print(df.describe()) # 统计摘要
print(df.head(2)) # 前 2 行
print(df.tail(1)) # 最后 1 行
19.3.2 数据选择
# 列选择
df["name"] # 单列(Series)
df[["name", "age"]] # 多列(DataFrame)
# 行选择
df.iloc[0] # 按位置
df.iloc[0:2] # 切片
df.loc[0] # 按标签
# 条件筛选
df[df["age"] > 25]
df.query("age > 25")
df[df["city"].isin(["北京", "上海"])]
19.3.3 数据处理
# 添加列
df["salary"] = [20000, 15000, 25000]
# 删除列
df.drop(columns=["salary"], inplace=True)
# 排序
df.sort_values("age", ascending=False)
# 分组聚合
df.groupby("city")["age"].mean()
# 缺失值
df.isna() # 检查缺失
df.fillna(0) # 填充缺失
df.dropna() # 删除缺失行
# 去重
df.drop_duplicates()
# 应用函数
df["age_group"] = df["age"].apply(lambda x: "青年" if x < 30 else "中年")
19.3.4 读写数据
# CSV
df = pd.read_csv("data.csv")
df.to_csv("output.csv", index=False, encoding="utf-8-sig")
# Excel
df = pd.read_excel("data.xlsx", sheet_name="Sheet1")
df.to_excel("output.xlsx", index=False)
# JSON
df = pd.read_json("data.json")
df.to_json("output.json", orient="records", force_ascii=False)
# 数据库
from sqlalchemy import create_engine
engine = create_engine("sqlite:///app.db")
df = pd.read_sql("SELECT * FROM users", engine)
df.to_sql("users", engine, if_exists="append", index=False)
19.4 Matplotlib
19.4.1 基本图表
import matplotlib.pyplot as plt
import numpy as np
# 折线图
x = np.linspace(0, 10, 100)
plt.figure(figsize=(10, 6))
plt.plot(x, np.sin(x), label="sin(x)")
plt.plot(x, np.cos(x), label="cos(x)")
plt.xlabel("x")
plt.ylabel("y")
plt.title("三角函数")
plt.legend()
plt.grid(True)
plt.savefig("trig.png", dpi=150, bbox_inches="tight")
plt.show()
19.4.2 常用图表类型
# 柱状图
categories = ["Python", "Java", "C++", "Go"]
values = [45, 30, 15, 10]
plt.bar(categories, values, color=["#3776AB", "#F89820", "#00599C", "#00ADD8"])
# 饼图
plt.pie(values, labels=categories, autopct="%1.1f%%")
# 散点图
x = np.random.randn(100)
y = x * 2 + np.random.randn(100) * 0.5
plt.scatter(x, y, alpha=0.6)
# 直方图
data = np.random.randn(1000)
plt.hist(data, bins=30, edgecolor="black")
19.4.3 Pandas 内置绘图
df = pd.DataFrame({
"月份": ["1月", "2月", "3月", "4月"],
"销售额": [100, 120, 115, 140],
"利润": [20, 25, 22, 30],
})
df.plot(x="月份", y=["销售额", "利润"], kind="bar", figsize=(10, 6))
plt.savefig("sales.png")
19.5 数据处理实战
import pandas as pd
import numpy as np
# 加载数据
df = pd.read_csv("sales.csv")
# 数据清洗
df = df.dropna(subset=["amount"])
df["date"] = pd.to_datetime(df["date"])
df["amount"] = df["amount"].astype(float)
# 特征工程
df["year"] = df["date"].dt.year
df["month"] = df["date"].dt.month
df["weekday"] = df["date"].dt.day_name()
# 分析
monthly = df.groupby("month")["amount"].agg(["sum", "mean", "count"])
monthly.columns = ["总销售额", "平均订单额", "订单数"]
# 导出
monthly.to_excel("monthly_report.xlsx")
print(monthly)
19.6 注意事项
🔴 注意:
- 大数据集避免用 Python 循环,使用 NumPy/Pandas 向量化操作
- Pandas 的
SettingWithCopyWarning提醒链式赋值问题 - Matplotlib 中文显示需要配置字体
- Jupyter Notebook 不适合生产代码,适合探索分析
💡 提示:
- 使用
df.info()和df.describe()快速了解数据 - 使用
df.query()替代复杂的布尔索引 - 使用
seaborn或plotly创建更美观的图表 - 大数据考虑使用
Polars替代 Pandas
📌 业务场景:
import pandas as pd
def generate_sales_report(csv_path: str, output_path: str):
"""生成销售报告。"""
df = pd.read_csv(csv_path, parse_dates=["date"])
# 按产品和月份汇总
summary = df.groupby([df["date"].dt.to_period("M"), "product"]).agg(
total_sales=("amount", "sum"),
order_count=("amount", "count"),
avg_order=("amount", "mean"),
).round(2)
# 导出
with pd.ExcelWriter(output_path) as writer:
summary.to_excel(writer, sheet_name="汇总")
df.pivot_table(values="amount", index="product", columns=df["date"].dt.month, aggfunc="sum").to_excel(writer, sheet_name="产品-月份")
print(f"报告已生成: {output_path}")
19.7 扩展阅读
- NumPy 文档
- Pandas 文档
- Matplotlib 文档
- Jupyter 文档
- 《利用 Python 进行数据分析》by Wes McKinney