Xz's blog Xz's blog
首页
时间序列
多模态
合成生物学
其他方向
生活
工具相关
PyTorch
导航站

Xu Zhen

首页
时间序列
多模态
合成生物学
其他方向
生活
工具相关
PyTorch
导航站
  • 零基础从零实现mini Pytorch

  • PyTorch基础知识

  • Python基础

    • Pandas教程
      • 🧭 学习路线图
      • ✅ 第一阶段:了解 Pandas 的两大数据结构
        • 📌 1.1 导入 Pandas
        • 📌 1.2 Series(一维数据)
        • 📌 1.3 DataFrame(二维表格)
      • ✅ 第二阶段:数据读取与写入(CSV、Excel、JSON)
        • 📌 2.1 读取 CSV 文件
        • 📌 2.2 写出 CSV 文件
        • 📌 2.3 读取 Excel 文件
        • 📌 2.4 写出 Excel 文件
        • 📌 2.5 读取 JSON 文件
        • 🎯 总结
      • ✅ 第三阶段:数据的选择与过滤
        • 🔹 3.1 选取列(Column Selection)
        • 🔹 3.2 选取行(Row Selection)
        • 使用 iloc(按位置)
        • 使用 loc(按标签)
        • 🔹 3.3 条件过滤(Boolean Indexing)
        • 🔹 3.4 条件赋值
        • 🔹 3.5 索引
        • 🧠 什么是索引(Index)?
        • 🔹 1. 单列索引(单层索引)
        • 设置索引
        • 访问元素
        • 🔹 2. 多列索引(多层索引 / MultiIndex)
        • 设置多列为索引
        • 访问多层索引的数据
        • 🔹 3. loc 和 iloc 的区别
        • 🔹 4. 恢复索引(reset_index)
        • 🔹 5. 设置索引时的参数
        • 🔹 6. 索引对象的属性和操作
        • 🔹 7. 索引的常见用途
        • ✅ 小结
      • ✅ 第四阶段:数据清洗与预处理
        • 🔹 4.1 缺失值处理(NaN)
        • 创建一个有缺失值的 DataFrame:
        • 查找缺失值
        • 删除缺失值
        • 填充缺失值
        • 🔹 4.2 重命名列名或索引
        • 🔹 4.3 删除重复数据
        • 🔹 4.4 数据类型转换
        • 🔹 4.5 重设索引、修改列顺序
        • ✅ 小结表格
        • 🧪 练习
      • ✅ 第五阶段:数据分组与聚合(GroupBy)
        • 🔹 5.1 基本分组与聚合
        • 🔹 5.2 多列聚合
        • 🔹 5.3 多列分组
        • 🔹 5.4 使用 agg() 自定义多个聚合操作
        • 🔹 5.5 重置索引与排序
        • ✅ 小结表格
        • 🧪 练习
      • ✅ 第六阶段:数据合并与连接
        • 🔹 6.1 使用 concat() 拼接数据
        • 👉 按行拼接(纵向合并)
        • 👉 按列拼接(横向合并)
        • 🔹 6.2 使用 merge() 进行关联合并(推荐)
        • 设置连接方式:how 参数
        • 🔹 6.3 使用 join()(按索引连接)
        • ✅ 小结对比表格
        • 🧪 练习
      • ✅ 第七阶段:时间序列处理(Datetime & Resampling)
        • 🔹 7.1 将字符串转换为 datetime 类型
        • 🔹 7.2 设置时间列为索引
        • 🔹 7.3 按时间筛选数据
        • 🔹 7.4 重采样(Resampling)
        • 🔹 7.5 滚动窗口(Rolling)
        • 🔹 7.6 提取年/月/日等时间字段
        • 🧪 练习
        • ✅ 小结表格
      • ✅ 第八阶段:Pandas 可视化(基于 Matplotlib)
        • 🔹 8.1 准备工作:导入绘图库
        • 🔹 8.2 折线图(line plot)——默认图
        • 🔹 8.3 条形图(bar plot)
        • 🔹 8.4 直方图(histogram)
        • 🔹 8.5 箱线图(box plot)
        • 🔹 8.6 散点图(scatter plot)
        • ✅ 小结表格
        • 🧪 练习
  • PyTorch学习笔记
  • Python基础
xuzhen
2025-07-18
目录

Pandas教程

# 🧭 学习路线图

我们将分为几个阶段来学习 pandas:

  1. 入门:了解数据结构
  2. 数据读取与写入
  3. 数据选取与过滤
  4. 数据清洗与预处理
  5. 数据聚合与分组
  6. 数据合并与连接
  7. 时间序列处理(可选)
  8. 可视化(可选)

# ✅ 第一阶段:了解 Pandas 的两大数据结构

Pandas 最核心的两个数据结构是:

  • Series: 一维数据(类似列表)
  • DataFrame: 二维表格(类似 Excel 表格或数据库)

# 📌 1.1 导入 Pandas

import pandas as pd
1

# 📌 1.2 Series(一维数据)

import pandas as pd

data = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])
print(data)
1
2
3
4

输出:

a    10
b    20
c    30
d    40
dtype: int64
1
2
3
4
5

你可以像操作字典一样访问它:

print(data['b'])  # 输出 20
1

# 📌 1.3 DataFrame(二维表格)

import pandas as pd

data = {
    'name': ['Alice', 'Bob', 'Charlie'],
    'age': [25, 30, 35],
    'city': ['Beijing', 'Shanghai', 'Guangzhou']
}
df = pd.DataFrame(data)
print(df)
1
2
3
4
5
6
7
8
9

输出:

     name  age      city
0   Alice   25   Beijing
1     Bob   30  Shanghai
2  Charlie   35  Guangzhou
1
2
3
4

你可以访问行、列或单个元素:

print(df['name'])      # 输出 name 列
print(df.loc[1])       # 按标签访问第2行(索引为1)
print(df.iloc[0, 2])   # 按位置访问第1行第3列
1
2
3

# ✅ 第二阶段:数据读取与写入(CSV、Excel、JSON)

Pandas 支持多种格式的数据读取和写出,最常见的是:

  • .csv:逗号分隔文本(最常用)
  • .xlsx:Excel 文件
  • .json:JSON 文件

# 📌 2.1 读取 CSV 文件

假设你有一个叫 data.csv 的文件内容如下:

name,age,city
Alice,25,Beijing
Bob,30,Shanghai
Charlie,35,Guangzhou
1
2
3
4

使用 Pandas 读取它:

import pandas as pd

df = pd.read_csv('data.csv')
print(df)
1
2
3
4

输出:

     name  age      city
0   Alice   25   Beijing
1     Bob   30  Shanghai
2  Charlie   35  Guangzhou
1
2
3
4

# 📌 2.2 写出 CSV 文件

你可以把 DataFrame 写回文件:

df.to_csv('output.csv', index=False)  # index=False 表示不写行索引
1

# 📌 2.3 读取 Excel 文件

如果你有一个 data.xlsx:

df = pd.read_excel('data.xlsx')
print(df)
1
2

📌 注意:你可能需要安装 openpyxl:

pip install openpyxl
1

# 📌 2.4 写出 Excel 文件

df.to_excel('output.xlsx', index=False)
1

# 📌 2.5 读取 JSON 文件

假设你有一个 data.json:

[
  {"name": "Alice", "age": 25, "city": "Beijing"},
  {"name": "Bob", "age": 30, "city": "Shanghai"}
]
1
2
3
4

读取方式:

df = pd.read_json('data.json')
print(df)
1
2

# 🎯 总结

格式 读取函数 写出函数
CSV pd.read_csv() df.to_csv()
Excel pd.read_excel() df.to_excel()
JSON pd.read_json() df.to_json()

# ✅ 第三阶段:数据的选择与过滤

这一阶段我们重点掌握:

  1. 选取列(列筛选)
  2. 选取行(按索引或条件)
  3. 按条件过滤数据
  4. 使用 loc 和 iloc 精确定位数据

数据的选择与过滤代码例子,每个详解可以先看下方,然后逐步看这个代码:

import pandas as pd
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'David'],
    'age': [25, 30, 35, 28],
    'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Beijing']
})

# 选取一列
print("选取一列:")
print(type(df['name']))
print(df['name'])

# 选取多列
print("\n选取多列:")
print(type(df[['name', 'city']]))
print(df[['name', 'city']])

# 使用 `iloc`(按位置)选取行
print("\n使用 `iloc` 选取行:")
print(type(df.iloc[0]))
print(df.iloc[0])  # 选取第一行
print(type(df.iloc[0:2]))  # 选取前两行
print(df.iloc[0:2])  # 选取前两行

# 使用 `loc`(按标签)选取行
print("\n使用 `loc` 选取行:")
print("设置1个列索引:")
df_t = df.set_index('name')  # 将 'name' 列设置为索引
print(type(df_t.loc['Alice']))  # 选取标签为 'Alice' 的行
print(df_t.loc['Alice'])
print("设置2个列索引:")
df_t2 = df.set_index(['name', 'city'])
print(type(df_t2.loc[('Alice', 'Beijing')]))  # 选取标签为 ('Alice', 'Beijing') 的行
print(df_t2.loc[('Alice', 'Beijing')])

# 使用条件筛选
print("\n使用条件筛选:")
print(type(df[df['age'] > 30]))  # 筛选年龄大于30的行
print(df[df['age'] > 30])
print(type(df[df['city'] == 'Beijing']))  # 筛选城市为 'Beijing' 的行
print(df[df['city'] == 'Beijing'])

print("\n使用条件筛选(多条件):")
# 与操作(同时满足)
print(df[(df['age'] > 25) & (df['city'] == 'Beijing')])
# 或操作(满足其一)
print("\n或操作(满足其一):")
print(df[(df['age'] > 30) | (df['city'] == 'Shanghai')])

print("\n条件赋值:")
# 添加新列:是否超过30岁
df['is_old'] = df['age'] > 30
print(df)
# 删除列
print("\n删除列:")
df.drop(columns=['is_old'], inplace=True)
print(df)

# 更改某些值
print("\n更改某些值:")
df.loc[df['age'] > 30, 'city'] = 'SeniorCity'
print(df)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

# 🔹 3.1 选取列(Column Selection)

选取一列:

df['name']
'''
<class 'pandas.core.series.Series'>
0      Alice
1        Bob
2    Charlie
3      David
Name: name, dtype: object
'''
1
2
3
4
5
6
7
8
9

选取多列(放在列表中):

df[['name', 'city']]
'''
<class 'pandas.core.frame.DataFrame'>
      name       city
0    Alice    Beijing
1      Bob   Shanghai
2  Charlie  Guangzhou
3    David    Beijing
'''
1
2
3
4
5
6
7
8
9

# 🔹 3.2 选取行(Row Selection)

默认 DataFrame 是以数字作为索引(0, 1, 2...)

# 使用 iloc(按位置)

df.iloc[0]           # 第一行
df.iloc[0:2]         # 第1到第2行(不包括第3行)
'''
<class 'pandas.core.series.Series'>
name      Alice
age          25
city    Beijing
Name: 0, dtype: object

<class 'pandas.core.frame.DataFrame'>
    name  age      city
0  Alice   25   Beijing
1    Bob   30  Shanghai
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 使用 loc(按标签)

如果你自己设置了索引(比如用姓名作为索引):

df = df.set_index('name')
df.loc['Alice']       # 按标签选行
'''
<class 'pandas.core.series.Series'>
age          25
city    Beijing
Name: Alice, dtype: object
'''
1
2
3
4
5
6
7
8

设置两个索引:

df = df.set_index(['name', 'city'])
print(type(df_t2.loc[('Alice', 'Beijing')]))  # 选取标签为 ('Alice', 'Beijing') 的行
print(df_t2.loc[('Alice', 'Beijing')])
'''
<class 'pandas.core.series.Series'>
age    25
Name: (Alice, Beijing), dtype: int64
'''
1
2
3
4
5
6
7
8

# 🔹 3.3 条件过滤(Boolean Indexing)

# 筛选年龄大于30的人
df[df['age'] > 30]
'''
<class 'pandas.core.frame.DataFrame'>
      name  age       city
2  Charlie   35  Guangzhou
'''

# 筛选城市是 Beijing 的人
df[df['city'] == 'Beijing']
'''
<class 'pandas.core.frame.DataFrame'>
    name  age     city
0  Alice   25  Beijing
3  David   28  Beijing
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

组合多个条件:

# 与操作(同时满足)
df[(df['age'] > 25) & (df['city'] == 'Beijing')]
'''
    name  age     city
3  David   28  Beijing
'''

# 或操作(满足其一)
df[(df['age'] > 30) | (df['city'] == 'Shanghai')]
'''
      name  age       city
1      Bob   30   Shanghai
2  Charlie   35  Guangzhou
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14

注意:逻辑运算符要用 &(与) 和 |(或),每个条件都要用括号括起来。


# 🔹 3.4 条件赋值

# 添加新列:是否超过30岁,is_old变量名起的好像不太好,就这样吧。。。
df['is_old'] = df['age'] > 30
'''
      name  age       city  is_old
0    Alice   25    Beijing   False
1      Bob   30   Shanghai   False
2  Charlie   35  Guangzhou    True
3    David   28    Beijing   False
'''

# 删除列
df.drop(columns=['is_old'], inplace=True)
'''
      name  age       city
0    Alice   25    Beijing
1      Bob   30   Shanghai
2  Charlie   35  Guangzhou
3    David   28    Beijing
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

也可以直接更改某些值:

df.loc[df['age'] > 30, 'city'] = 'SeniorCity'
'''
      name  age        city
0    Alice   25     Beijing
1      Bob   30    Shanghai
2  Charlie   35  SeniorCity
3    David   28     Beijing
'''
1
2
3
4
5
6
7
8

# 🔹 3.5 索引

# 🧠 什么是索引(Index)?

在 pandas 中,索引是用于标识数据标签的机制。它可以是数字、字符串,甚至多个列组成的多重索引(MultiIndex)。

import pandas as pd

df = pd.DataFrame({
    'name': ['Alice', 'Alice', 'Bob'],
    'city': ['Beijing', 'Shanghai', 'Shanghai'],
    'score': [85, 90, 88]
})
print(df)  # 默认是 RangeIndex
'''
    name      city  score
0  Alice   Beijing     85
1  Alice  Shanghai     90
2    Bob  Shanghai     88
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 🔹 1. 单列索引(单层索引)

# 设置索引
df = df.set_index('name')
'''
        city  score
name                  
Alice   Beijing     85
Alice  Shanghai     90
Bob    Shanghai     88
'''
1
2
3
4
5
6
7
8

这将 name 列作为索引,原来的行号就被替代了。

# 访问元素
df.loc['Alice']
1

# 🔹 2. 多列索引(多层索引 / MultiIndex)

# 设置多列为索引
df = pd.DataFrame({
    'name': ['Alice', 'Alice', 'Bob'],
    'city': ['Beijing', 'Shanghai', 'Shanghai'],
    'score': [85, 90, 88]
})
df_multi = df.set_index(['name', 'city'])
1
2
3
4
5
6

此时索引是 (name, city) 的多层结构:

                 score
name   city          
Alice  Beijing     85
       Shanghai    90
Bob    Shanghai    88
1
2
3
4
5
# 访问多层索引的数据
df_multi.loc[('Alice', 'Beijing')]
1

# 🔹 3. loc 和 iloc 的区别

方法 依据 示例
.loc 按“标签”查找 df.loc['Alice']
.iloc 按“位置”查找 df.iloc[0]

# 🔹 4. 恢复索引(reset_index)

将索引还原为列:

df_reset = df_multi.reset_index()
1

# 🔹 5. 设置索引时的参数

df.set_index('col_name', inplace=True, drop=False)
1
参数 作用
inplace 是否就地修改(默认 False)
drop 是否从列中删除索引列(默认 True)

# 🔹 6. 索引对象的属性和操作

df.index            # 查看索引
df.index.name       # 获取索引名称
df.index.names      # 获取多层索引的所有名称
df.index.is_unique  # 是否唯一
df.index.tolist()   # 转为列表
1
2
3
4
5

# 🔹 7. 索引的常见用途

  • 快速查找数据(相比遍历效率高)
  • 数据对齐(merge、join、concat)
  • 分组聚合(groupby)
  • 分层结构(多维数据)

# ✅ 小结

操作 方法
选列 df['列名'] 或 df[['列1', '列2']]
选行(按位置) df.iloc[行号]
选行(按标签) df.loc[标签]
条件筛选 df[df['列'] > 某值]
多条件筛选 (条件1) & (条件2)
条件修改 df.loc[条件, '列'] = 新值

# ✅ 第四阶段:数据清洗与预处理

这一阶段你将学到:

  1. 缺失值(NaN)的处理
  2. 重命名列名或索引
  3. 删除重复数据
  4. 数据类型转换
  5. 修改列顺序、重设索引

# 🔹 4.1 缺失值处理(NaN)

# 创建一个有缺失值的 DataFrame:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', None],
    'age': [25, None, 35, 40],
    'city': ['Beijing', 'Shanghai', None, 'Guangzhou']
})
print(df)
1
2
3
4
5
6
7
8
9

# 查找缺失值

df.isnull()          # 查看哪些位置是缺失的
df.isnull().sum()    # 每列缺失值数量
1
2

# 删除缺失值

df.dropna()                  # 删除含有缺失值的行
df.dropna(axis=1)           # 删除含有缺失值的列
1
2

# 填充缺失值

df = df.fillna(0)                # 所有缺失值填 0
df['age'] = df['age'].fillna(df['age'].mean())  # 填平均值
df['name'] = df['name'].fillna('Unknown')        # 填字符串
1
2
3

# 🔹 4.2 重命名列名或索引

df.rename(columns={'name': 'Name', 'age': 'Age'})
df.rename(index={0: 'first', 1: 'second'})
1
2

也可以一次性改全部列名:

df.columns = ['Name', 'Age', 'City']
1

# 🔹 4.3 删除重复数据

df = pd.DataFrame({
    'name': ['A', 'B', 'A', 'C'],
    'score': [90, 85, 90, 78]
})

df.duplicated()           # 查看哪些是重复行
df.drop_duplicates()      # 删除重复行
1
2
3
4
5
6
7

# 🔹 4.4 数据类型转换

df['age'] = df['age'].astype(int)       # 转整数(前提是不能有NaN)
df['age'] = pd.to_numeric(df['age'], errors='coerce')  # 自动转失败的填NaN
1
2

日期转换:

df['date'] = pd.to_datetime(df['date'])
1

# 🔹 4.5 重设索引、修改列顺序

重设索引:

df.reset_index(drop=True, inplace=True)
1

修改列顺序:

df = df[['city', 'name', 'age']]  # 指定你想要的顺序
1

# ✅ 小结表格

任务 方法
查找缺失值 df.isnull()
删除缺失值 df.dropna()
填补缺失值 df.fillna(value)
重命名列名 df.rename(columns={})
删除重复行 df.drop_duplicates()
类型转换 df['col'].astype(type)
转日期格式 pd.to_datetime(df['col'])
重设索引 df.reset_index()

# 🧪 练习

import pandas as pd
import numpy as np

data = {
    'name': ['A', 'B', 'C', None],
    'score': [90, np.nan, 75, 88],
    'date': ['2024-01-01', '2024-01-02', None, '2024-01-04']
}
df = pd.DataFrame(data)

# 1. 查看缺失
print(df.isnull().sum())

# 2. 用平均分填补缺失分数
df['score'] = df['score'].fillna(df['score'].mean())

# 3. 将日期列转为 datetime 类型
df['date'] = pd.to_datetime(df['date'])

# 4. 填补缺失的名字
df['name'] = df['name'].fillna('Unknown')

print(df)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

很好,我们现在进入 Pandas 的 第五阶段:数据分组与聚合(GroupBy),这是进行统计分析和数据总结时非常强大的工具。


# ✅ 第五阶段:数据分组与聚合(GroupBy)

这一阶段将讲解:

  1. 如何按列分组(groupby)
  2. 如何聚合(sum、mean、count 等)
  3. 多层分组与聚合
  4. 自定义聚合函数

# 🔹 5.1 基本分组与聚合

import pandas as pd

df = pd.DataFrame({
    'department': ['HR', 'HR', 'IT', 'IT', 'Sales', 'Sales'],
    'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank'],
    'salary': [5000, 5200, 6000, 6200, 4000, 4200]
})

# 按部门求平均薪资
df.groupby('department')['salary'].mean()
1
2
3
4
5
6
7
8
9
10

输出:

department
HR       5100.0
IT       6100.0
Sales    4100.0
Name: salary, dtype: float64
1
2
3
4
5

# 🔹 5.2 多列聚合

df.groupby('department')[['salary']].agg(['mean', 'max', 'min'])
1

输出:

            salary          
              mean   max   min
department                    
HR           5100  5200  5000
IT           6100  6200  6000
Sales        4100  4200  4000
1
2
3
4
5
6

# 🔹 5.3 多列分组

df = pd.DataFrame({
    'department': ['HR', 'HR', 'IT', 'IT', 'Sales', 'Sales'],
    'gender': ['F', 'M', 'M', 'M', 'F', 'M'],
    'salary': [5000, 5200, 6000, 6200, 4000, 4200]
})

# 按部门和性别分组
df.groupby(['department', 'gender'])['salary'].mean()
1
2
3
4
5
6
7
8

输出:

department  gender
HR          F         5000.0
            M         5200.0
IT          M         6100.0
Sales       F         4000.0
            M         4200.0
Name: salary, dtype: float64
1
2
3
4
5
6
7

# 🔹 5.4 使用 agg() 自定义多个聚合操作

# 多列多个聚合函数
df.groupby('department').agg({
    'salary': ['mean', 'std'],
    'gender': 'count'
})
1
2
3
4
5

输出:

            salary           gender
              mean        std  count
department                         
HR           5100.0  141.421356      2
IT           6100.0  141.421356      2
Sales        4100.0  141.421356      2
1
2
3
4
5
6

# 🔹 5.5 重置索引与排序

GroupBy 会默认以分组列作为索引,可以重置:

grouped = df.groupby('department')['salary'].mean().reset_index()
1

排序:

grouped.sort_values(by='salary', ascending=False)
1

# ✅ 小结表格

操作 示例
单列分组 df.groupby('col')
聚合函数 .mean(), .sum(), .count(), .max()
多列聚合 .agg({'col1': 'mean', 'col2': 'count'})
多重分组 df.groupby(['col1', 'col2'])
重置索引 .reset_index()
排序 .sort_values(by='col')

# 🧪 练习

df = pd.DataFrame({
    'city': ['Beijing', 'Beijing', 'Shanghai', 'Shanghai', 'Beijing'],
    'store': ['A', 'B', 'A', 'B', 'A'],
    'sales': [100, 150, 200, 250, 120]
})

# 每个城市的平均销售额
print(df.groupby('city')['sales'].mean())

# 每个城市、每个店的总销售额
print(df.groupby(['city', 'store'])['sales'].sum().reset_index())
1
2
3
4
5
6
7
8
9
10
11

# ✅ 第六阶段:数据合并与连接

现在进入 第六阶段:数据合并与连接(Merge / Join / Concat),这是处理多张表时的核心技能,功能和 SQL 里的 JOIN 很相似。

下面将学到以下几种表格合并方式:

  1. concat():上下/左右拼接
  2. merge():根据某列进行关联合并(类似 SQL 中的 JOIN)
  3. join():使用索引连接

# 🔹 6.1 使用 concat() 拼接数据

# 👉 按行拼接(纵向合并)

import pandas as pd

df1 = pd.DataFrame({
    'name': ['Alice', 'Bob'],
    'age': [25, 30]
})

df2 = pd.DataFrame({
    'name': ['Charlie', 'David'],
    'age': [35, 40]
})

result = pd.concat([df1, df2], ignore_index=True)
print(result)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

输出:

      name  age
0    Alice   25
1      Bob   30
2  Charlie   35
3    David   40
1
2
3
4
5

# 👉 按列拼接(横向合并)

df3 = pd.DataFrame({
    'city': ['Beijing', 'Shanghai']
})

result = pd.concat([df1, df3], axis=1)
print(result)
1
2
3
4
5
6

输出:

    name  age      city
0  Alice   25   Beijing
1    Bob   30  Shanghai
1
2
3

# 🔹 6.2 使用 merge() 进行关联合并(推荐)

这是最常用的合并方式,和 SQL 的 JOIN 一样强大。

df_left = pd.DataFrame({
    'employee': ['Alice', 'Bob', 'Charlie'],
    'dept_id': [1, 2, 3]
})

df_right = pd.DataFrame({
    'dept_id': [1, 2],
    'dept_name': ['HR', 'IT']
})

# 默认是 inner join(只保留匹配的)
merged = pd.merge(df_left, df_right, on='dept_id')
print(merged)
1
2
3
4
5
6
7
8
9
10
11
12
13

输出:

  employee  dept_id dept_name
0    Alice        1        HR
1      Bob        2        IT
1
2
3

# 设置连接方式:how 参数

参数 含义
'inner' 默认,交集
'left' 左连接
'right' 右连接
'outer' 并集,NaN 补全
pd.merge(df_left, df_right, on='dept_id', how='outer')
1

# 🔹 6.3 使用 join()(按索引连接)

df1 = pd.DataFrame({'salary': [5000, 6000]}, index=['Alice', 'Bob'])
df2 = pd.DataFrame({'age': [25, 30]}, index=['Alice', 'Bob'])

joined = df1.join(df2)
print(joined)
1
2
3
4
5

输出:

       salary  age
Alice    5000   25
Bob      6000   30
1
2
3

# ✅ 小结对比表格

方法 用途 默认连接方式 支持 on 关键字?
concat() 拼接多个 DataFrame 无 ❌
merge() 类似 SQL join inner ✅
join() 按索引连接 left ❌

# 🧪 练习

df_emp = pd.DataFrame({
    'name': ['A', 'B', 'C'],
    'dept_id': [1, 2, 3]
})

df_dept = pd.DataFrame({
    'dept_id': [1, 2],
    'dept_name': ['HR', 'Sales']
})

# 左连接(保留所有员工)
merged = pd.merge(df_emp, df_dept, on='dept_id', how='left')
print(merged)
1
2
3
4
5
6
7
8
9
10
11
12
13

# ✅ 第七阶段:时间序列处理(Datetime & Resampling)

将学会到:

  1. 将日期列转换为 datetime 类型
  2. 设置时间为索引
  3. 按日期筛选、分组
  4. 重新采样(如按月、按日汇总)
  5. 滚动窗口计算(移动平均)

# 🔹 7.1 将字符串转换为 datetime 类型

import pandas as pd

df = pd.DataFrame({
    'date': ['2024-01-01', '2024-01-02', '2024-01-03'],
    'value': [100, 120, 130]
})

df['date'] = pd.to_datetime(df['date'])
print(df.dtypes)
print(df)
1
2
3
4
5
6
7
8
9
10

输出:

date     datetime64[ns]
value             int64
dtype: object
        date  value
0 2024-01-01    100
1 2024-01-02    120
2 2024-01-03    130
1
2
3
4
5
6
7

# 🔹 7.2 设置时间列为索引

df = df.set_index('date')
print(df)
1
2

输出:

            value
date             
2024-01-01    100
2024-01-02    120
2024-01-03    130
1
2
3
4
5

这样就可以使用很多时间相关的操作了。


# 🔹 7.3 按时间筛选数据

# 取2024年1月之后的数据
df['2024-01-02':]
1
2

# 🔹 7.4 重采样(Resampling)

Resample 可以将数据按天、月、季度等频率进行汇总。

# 构造示例数据
df = pd.DataFrame({
    'date': pd.date_range(start='2024-01-01', periods=10, freq='D'),
    'sales': [100, 120, 110, 130, 150, 140, 160, 170, 180, 200]
})
df.set_index('date', inplace=True)

# 按周求和
weekly = df.resample('W').sum()
print(weekly)
1
2
3
4
5
6
7
8
9
10

常用频率:

代码 含义
'D' 每天
'W' 每周
'M' 每月
'Q' 每季度
'A' 每年

# 🔹 7.5 滚动窗口(Rolling)

用于计算移动平均等。

# 3天移动平均
df['rolling_mean'] = df['sales'].rolling(window=3).mean()
print(df)
1
2
3

# 🔹 7.6 提取年/月/日等时间字段

df['year'] = df.index.year
df['month'] = df.index.month
df['day'] = df.index.day
1
2
3

# 🧪 练习

import pandas as pd

df = pd.DataFrame({
    'date': pd.date_range('2024-01-01', periods=12, freq='D'),
    'temperature': [22, 23, 21, 24, 25, 26, 24, 23, 22, 21, 20, 19]
})
df.set_index('date', inplace=True)

# 1. 每周平均温度
print(df.resample('W').mean())

# 2. 3天滑动平均
df['avg_3d'] = df['temperature'].rolling(3).mean()
print(df)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# ✅ 小结表格

操作 方法
转换为 datetime pd.to_datetime()
设置时间索引 df.set_index('date')
按时间筛选 df['2024-01':'2024-03']
重采样 df.resample('M').sum()
滚动平均 df.rolling(3).mean()

# ✅ 第八阶段:Pandas 可视化(基于 Matplotlib)

Pandas 自带可视化功能,底层基于 Matplotlib。常见图表有:

  1. 折线图(line plot)
  2. 条形图(bar plot)
  3. 直方图(histogram)
  4. 箱线图(box plot)
  5. 散点图(scatter plot)

# 🔹 8.1 准备工作:导入绘图库

import pandas as pd
import matplotlib.pyplot as plt

# 使图像在 Jupyter/脚本中显示
plt.rcParams['font.family'] = 'Arial'  # 避免中文乱码时可改为 'SimHei'
1
2
3
4
5

# 🔹 8.2 折线图(line plot)——默认图

适合:时间序列趋势、连续值变化

df = pd.DataFrame({
    'day': ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
    'sales': [100, 120, 90, 130, 150]
})
df.plot(x='day', y='sales', kind='line', marker='o')
plt.title('Daily Sales Trend')
plt.ylabel('Sales')
plt.grid(True)
plt.show()
1
2
3
4
5
6
7
8
9

# 🔹 8.3 条形图(bar plot)

适合:类别型数据的对比

df.plot(x='day', y='sales', kind='bar', color='skyblue')
plt.title('Sales by Day')
plt.ylabel('Sales')
plt.xticks(rotation=0)
plt.show()
1
2
3
4
5

# 🔹 8.4 直方图(histogram)

适合:数据分布(如成绩分布)

df = pd.DataFrame({'score': [60, 65, 70, 72, 75, 80, 82, 85, 90, 92, 95, 100]})
df.plot(kind='hist', bins=5, rwidth=0.9)
plt.title('Score Distribution')
plt.xlabel('Score')
plt.show()
1
2
3
4
5

# 🔹 8.5 箱线图(box plot)

适合:看中位数、异常值、四分位数

df = pd.DataFrame({
    'Math': [80, 82, 90, 95, 100],
    'English': [70, 75, 85, 90, 92]
})
df.plot(kind='box')
plt.title('Score Boxplot')
plt.show()
1
2
3
4
5
6
7

# 🔹 8.6 散点图(scatter plot)

适合:看变量之间是否相关

df = pd.DataFrame({
    'hours_studied': [1, 2, 3, 4, 5, 6],
    'score': [50, 60, 65, 70, 85, 90]
})

df.plot(kind='scatter', x='hours_studied', y='score')
plt.title('Study Time vs Score')
plt.xlabel('Hours Studied')
plt.ylabel('Score')
plt.grid(True)
plt.show()
1
2
3
4
5
6
7
8
9
10
11

# ✅ 小结表格

图表类型 kind 类型 适用场景
折线图 'line' 趋势变化(如时间序列)
条形图 'bar' 类别比较(如每天销售)
直方图 'hist' 分布频率
箱线图 'box' 看异常值、中位数等
散点图 'scatter' 两个变量关系

# 🧪 练习

df = pd.DataFrame({
    'day': ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
    'sales': [100, 120, 90, 130, 150],
    'visitors': [300, 400, 350, 500, 550]
})

# 1. 折线图:每天销售趋势
df.plot(x='day', y='sales', kind='line', marker='o')
plt.title('Daily Sales')
plt.show()

# 2. 散点图:访问人数 vs 销售额
df.plot(kind='scatter', x='visitors', y='sales')
plt.title('Visitors vs Sales')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#Python
上次更新: 2025/07/21, 10:36:23

← register_buffer、nn.Parameter与torch.tensor比较

最近更新
01
Slice切片
07-26
02
引用与借用
07-26
03
所有权
07-26
更多文章>
Theme by Vdoing | Copyright © 2025-2025 Xu Zhen | 鲁ICP备2025169719号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式