Skip to content

Module 9: 数据科学核心库

NumPy、Pandas、Matplotlib —— Python 数据分析的三大支柱


本章概览

这是全书最重要的一章!本章将深入学习 Python 数据科学的核心库:NumPy(数值计算)、Pandas(数据处理)、Matplotlib/Seaborn(数据可视化)。掌握这三个库,你就掌握了 Python 数据分析的 80% 核心技能。

重要提示:这一章内容最多(6篇文章),但也最实用。建议预留 2-3 周时间深入学习和实践。


学习目标

学完本章后,你将能够:

  • 使用 NumPy 进行高效的数值计算
  • 使用 Pandas 读取、清洗、转换数据
  • 掌握 Pandas 的分组、合并、透视等高级操作
  • 使用 Matplotlib 和 Seaborn 创建专业图表
  • 计算描述性统计量
  • 使用 Requests 爬取网页数据
  • 构建完整的数据分析工作流

章节内容

01 - NumPy 基础

核心问题: 为什么需要 NumPy?

核心内容:

  • NumPy 是什么?
    • Python 科学计算的基础库
    • Pandas 基于 NumPy 构建
    • 比 Python 列表快 10-100 倍
  • 创建数组:
    python
    import numpy as np
    
    # 从列表创建
    ages = np.array([25, 30, 35, 40])
    
    # 特殊数组
    zeros = np.zeros(5)  # [0. 0. 0. 0. 0.]
    ones = np.ones(5)    # [1. 1. 1. 1. 1.]
    seq = np.arange(0, 10, 2)  # [0 2 4 6 8]
    
    # 随机数
    rand = np.random.rand(5)  # 0-1均匀分布
    randn = np.random.randn(5)  # 标准正态分布
  • 数组操作:
    • 向量化运算(无需循环)
    • 索引和切片
    • 统计函数:mean(), std(), sum(), max()
    • 线性代数:矩阵乘法、转置
  • 对比 R 和 Stata:
    • R: c(1, 2, 3) ≈ NumPy 数组
    • Stata: matrix 命令 ≈ NumPy

为什么重要?

  • Pandas DataFrame 的底层是 NumPy 数组
  • 理解 NumPy 帮助你更好地理解 Pandas
  • 数值计算和矩阵运算必备

实际应用:

python
# 生成模拟数据
np.random.seed(42)
n = 1000
education = np.random.normal(16, 2, n)  # 教育年限
income = 30000 + 5000 * education + np.random.normal(0, 10000, n)

# 计算相关系数
correlation = np.corrcoef(education, income)[0, 1]

02 - Pandas 入门

核心问题: 如何用 Pandas 处理表格数据?

核心内容:

  • Pandas 是什么?
    • Python 的"Excel/Stata"
    • 核心数据结构:DataFrame(表格)和 Series(列)
  • 创建 DataFrame:
    python
    import pandas as pd
    
    # 从字典创建
    df = pd.DataFrame({
        'age': [25, 30, 35],
        'income': [50000, 75000, 85000]
    })
    
    # 从 CSV 读取
    df = pd.read_csv('survey.csv')
  • 数据查看:
    • df.head():前几行
    • df.info():数据类型和缺失值
    • df.describe():描述性统计
    • df.shape:行数和列数
  • 数据选择:
    • 选择列:df['age']df[['age', 'income']]
    • 选择行:df.loc[0](按标签)、df.iloc[0](按位置)
    • 条件筛选:df[df['age'] > 30]
  • 数据操作:
    • 新列:df['log_income'] = np.log(df['income'])
    • 删除:df.drop('column', axis=1)
    • 排序:df.sort_values('income')
    • 重命名:df.rename(columns={'old': 'new'})

对比 Stata/R:

操作StataRPandas
选择列keep age incomedf[c('age', 'income')]df[['age', 'income']]
筛选keep if age > 30df[df$age > 30, ]df[df['age'] > 30]
新列gen log_income = log(income)df$log_income <- log(df$income)df['log_income'] = np.log(df['income'])

03 - Pandas 高级操作

核心问题: 如何进行复杂的数据处理?

核心内容:

  • 缺失值处理:
    python
    df.isnull().sum()  # 统计缺失值
    df.dropna()  # 删除缺失值
    df.fillna(df.mean())  # 填充均值
  • 分组聚合(GroupBy):
    python
    # 按性别分组计算平均收入
    df.groupby('gender')['income'].mean()
    
    # 多个统计量
    df.groupby('gender').agg({
        'income': ['mean', 'std', 'count'],
        'age': 'mean'
    })
  • 合并数据:
    python
    # 类似 SQL JOIN
    df_merged = pd.merge(df1, df2, on='id', how='left')
    
    # 纵向合并(追加行)
    df_combined = pd.concat([df1, df2], ignore_index=True)
  • 透视表(Pivot Table):
    python
    # 类似 Excel 透视表
    pivot = df.pivot_table(
        values='income',
        index='gender',
        columns='education_level',
        aggfunc='mean'
    )
  • 数据重塑:
    • melt():宽格式 → 长格式
    • pivot():长格式 → 宽格式
  • Apply 和自定义函数:
    python
    df['income_category'] = df['income'].apply(
        lambda x: '高收入' if x > 80000 else '中低收入'
    )

对比 Stata:

操作StataPandas
分组统计bysort gender: summarize incomedf.groupby('gender')['income'].describe()
合并merge 1:1 id using other.dtapd.merge(df1, df2, on='id')
透视table gender education, c(mean income)df.pivot_table(...)
重塑reshapemelt() / pivot()

04 - Matplotlib 与 Seaborn

核心问题: 如何创建专业的数据可视化?

核心内容:

  • Matplotlib 基础:
    python
    import matplotlib.pyplot as plt
    
    # 散点图
    plt.scatter(df['education'], df['income'])
    plt.xlabel('Education Years')
    plt.ylabel('Income ($)')
    plt.title('Education vs Income')
    plt.show()
    
    # 直方图
    plt.hist(df['age'], bins=20, edgecolor='black')
    plt.xlabel('Age')
    plt.ylabel('Frequency')
    plt.show()
  • Seaborn(更美观):
    python
    import seaborn as sns
    
    # 散点图 + 回归线
    sns.regplot(x='education', y='income', data=df)
    
    # 箱线图
    sns.boxplot(x='gender', y='income', data=df)
    
    # 热力图(相关系数)
    sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
  • 常用图表:
    • 散点图:变量关系
    • 直方图:分布
    • 箱线图:组间比较
    • 条形图:分类统计
    • 线图:时间序列
    • 热力图:相关矩阵
  • 子图和布局:
    python
    fig, axes = plt.subplots(2, 2, figsize=(12, 10))
    axes[0, 0].hist(df['age'])
    axes[0, 1].scatter(df['education'], df['income'])

对比 Stata/R:

  • Stata: graph twoway scatter, histogram
  • R: ggplot2(最强大的可视化库)
  • Python: Matplotlib(底层) + Seaborn(高层)

05 - 描述性统计

核心问题: 如何计算统计量?

核心内容:

  • 单变量统计:
    python
    # 均值、中位数、标准差
    df['income'].mean()
    df['income'].median()
    df['income'].std()
    
    # 分位数
    df['income'].quantile([0.25, 0.5, 0.75])
    
    # 完整描述
    df['income'].describe()
  • 分组统计:
    python
    df.groupby('gender')['income'].agg(['mean', 'std', 'count'])
  • 相关分析:
    python
    # 相关系数矩阵
    df[['age', 'education', 'income']].corr()
    
    # 两变量相关
    df['education'].corr(df['income'])
  • 频数分布:
    python
    # 频数表
    df['gender'].value_counts()
    
    # 交叉表
    pd.crosstab(df['gender'], df['education_level'])
  • 使用 scipy.stats:
    python
    from scipy import stats
    
    # t 检验
    stats.ttest_ind(group1, group2)
    
    # 卡方检验
    stats.chi2_contingency(crosstab)

对比 Stata:

操作StataPandas
描述统计summarizedf.describe()
分组统计bysort gender: summarize incomedf.groupby('gender')['income'].describe()
相关系数correlate income educationdf[['income', 'education']].corr()
频数表tabulate genderdf['gender'].value_counts()

06 - 网页爬取入门

核心问题: 如何获取网页数据?

核心内容:

  • Requests 库:
    python
    import requests
    
    # GET 请求
    response = requests.get('https://example.com')
    print(response.status_code)  # 200 表示成功
    print(response.text)  # HTML 内容
  • BeautifulSoup 解析 HTML:
    python
    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(response.text, 'html.parser')
    
    # 提取标题
    title = soup.find('title').text
    
    # 提取所有链接
    links = soup.find_all('a')
    for link in links:
        print(link.get('href'))
  • 实战案例:爬取表格数据:
    python
    # 爬取维基百科表格
    url = 'https://en.wikipedia.org/wiki/List_of_countries_by_GDP_(nominal)'
    tables = pd.read_html(url)  # 自动提取所有表格
    df = tables[0]  # 第一个表格
  • API 调用:
    python
    # 获取 JSON 数据
    response = requests.get('https://api.example.com/data')
    data = response.json()
    df = pd.DataFrame(data)
  • 注意事项:
    • 遵守 robots.txt
    • 添加延时,避免被封
    • 检查网站使用条款

社科应用:

  • 爬取新闻文章
  • 获取社交媒体数据
  • 下载公开数据集
  • 调用政府/学术 API

Python vs Stata vs R 数据分析对比

任务StataRPandas
读取数据use data.dtaread.csv()pd.read_csv()
查看数据describesummary()df.describe()
选择列keep age incomedf[c('age', 'income')]df[['age', 'income']]
筛选行keep if age > 30df[df$age > 30, ]df[df['age'] > 30]
新列gen log_income = log(income)df$log_income <- log(df$income)df['log_income'] = np.log(df['income'])
分组统计bysort gender: summarizeaggregate() / group_by()df.groupby().agg()
合并mergemerge()pd.merge()
可视化graphggplot2matplotlib / seaborn

如何学习本章?

学习路线(2-3 周)

第 1-2 天(4小时): NumPy 基础

  • 阅读 01 - NumPy 基础
  • 练习数组创建和操作
  • 理解向量化运算

第 3-5 天(10小时): Pandas 入门

  • 阅读 02 - Pandas 入门
  • 练习读取 CSV、筛选、新列
  • 完成练习题

第 6-8 天(10小时): Pandas 高级

  • 阅读 03 - Pandas 高级操作
  • 练习 GroupBy、Merge、Pivot
  • 用真实数据集练习

第 9-10 天(6小时): 数据可视化

  • 阅读 04 - Matplotlib 与 Seaborn
  • 创建各种图表
  • 美化图表

第 11 天(3小时): 描述性统计

  • 阅读 05 - 描述性统计
  • 计算统计量
  • 相关分析

第 12 天(3小时): 网页爬取(可选)

  • 阅读 06 - 网页爬取入门
  • 尝试爬取简单网页
  • 调用公开 API

总时间: 36 小时(2-3 周)

最小化学习路径

对于社科学生,绝对核心:

必学(日常分析必备,20小时):

  • 02 - Pandas 入门(完整学习)
  • 03 - Pandas 高级操作(GroupBy、Merge)
  • 04 - Matplotlib 基础(散点图、直方图、箱线图)
  • 05 - 描述性统计

重要(提升效率,10小时):

  • 01 - NumPy 基础(理解底层)
  • Seaborn 可视化
  • Pandas 链式调用

可选(特定需求):

  • 06 - 网页爬取(需要爬取数据时)
  • NumPy 线性代数
  • 高级可视化(Plotly 交互图表)

学习建议

  1. 边学边练,用真实数据

    • 不要只看示例代码
    • 下载真实数据集(Kaggle、UCI、政府数据)
    • 尝试复现论文的描述性统计表
  2. 建立 Pandas 思维方式

    python
    #  循环思维(慢且丑)
    for i in range(len(df)):
        if df.loc[i, 'age'] > 30:
            df.loc[i, 'age_group'] = 'old'
    
    #  Pandas 思维(快且优雅)
    df['age_group'] = df['age'].apply(lambda x: 'old' if x > 30 else 'young')
    # 或者
    df['age_group'] = np.where(df['age'] > 30, 'old', 'young')
  3. 记住常用操作的"惯用法"

    python
    # 读取数据
    df = pd.read_csv('data.csv')
    
    # 快速查看
    df.head()
    df.info()
    df.describe()
    
    # 数据清洗流水线
    df_clean = (df
        .dropna(subset=['age', 'income'])  # 删除缺失值
        .query('age >= 18 & age <= 100')   # 筛选
        .assign(log_income=lambda x: np.log(x['income']))  # 新列
        .sort_values('income')             # 排序
    )
  4. 实践项目:完整数据分析

    python
    # 项目:收入不等式分析
    
    # 1. 读取数据
    df = pd.read_csv('income_survey.csv')
    
    # 2. 数据清洗
    df_clean = df.dropna().query('age >= 18 & income > 0')
    
    # 3. 描述性统计
    print(df_clean.describe())
    print(df_clean.groupby('gender')['income'].mean())
    
    # 4. 可视化
    sns.boxplot(x='education_level', y='income', data=df_clean)
    sns.histplot(df_clean['income'], bins=50)
    
    # 5. 保存结果
    df_clean.to_csv('income_clean.csv', index=False)

常见问题

Q: NumPy 和 Pandas 有什么区别? A:

  • NumPy:数值计算,适合同质数据(全是数字)
  • Pandas:数据处理,适合异质数据(数字+文本)
  • Pandas 基于 NumPy 构建

Q: 什么时候用 loc,什么时候用 iloc? A:

  • loc:按标签(列名、行索引名称)
  • iloc:按位置(0, 1, 2...)
python
df.loc[0, 'age']  # 第 0 行,'age' 列
df.iloc[0, 1]     # 第 0 行,第 1 列

Q: 为什么我的 Pandas 代码很慢? A:

  • 不要用循环:for i in range(len(df))
  • 用向量化操作:df['new'] = df['old'] * 2
  • 用 apply:df['new'] = df['old'].apply(func)
  • 用 NumPy:df['new'] = np.log(df['old'])

Q: Matplotlib 和 Seaborn 选哪个? A:

  • Matplotlib:底层、灵活、复杂
  • Seaborn:高层、美观、简单
  • 建议:快速探索用 Seaborn,精细调整用 Matplotlib

Q: 如何学习 Pandas?记不住这么多函数! A:

  • 不要死记硬背
  • 记住核心操作:read_csv(), head(), query(), groupby(), merge()
  • 其他的用到时查文档
  • 多练习,形成肌肉记忆

下一步

完成本章后,你将掌握:

  • NumPy 数值计算和数组操作
  • Pandas 数据读取、清洗、转换
  • 分组聚合、数据合并、透视表
  • Matplotlib/Seaborn 数据可视化
  • 描述性统计分析
  • 网页数据爬取

Module 10 中,我们将学习机器学习和 LLM API 调用,探索更前沿的应用。

Module 11 中,我们将学习代码规范、调试和 Git,提升代码质量。

这是最重要的一章!掌握 NumPy 和 Pandas,你就掌握了 Python 数据分析的核心!


快速链接

基于 MIT 许可证发布。内容版权归作者所有。