pandas基础三

文章目录

聚合和分组的概念

一、概念解释

1. 分组(Grouping)

分组是将数据按照特定标准划分为多个组的操作。就像把一堆球按照颜色分类,红色球放一堆,蓝色球放一堆。

分组依据可以是:

  • 单个列(如"性别"、"地区")
  • 多个列组合(如"地区+性别")
  • Series对象
  • 字典(将列名映射到自定义分组)
  • 函数(对索引应用函数生成分组依据)

分组操作特点

  • 不进行实际计算,只是将数据组织成组
  • 返回一个GroupBy对象(表示分组的中间状态)
  • 通过groupby()方法实现

2. 聚合(Aggregation)

聚合是对每个组进行统计计算的操作。就像对每种颜色的球堆计算总数、平均重量等。

聚合操作特点

  • 对每个组应用统计函数
  • 返回每个组的统计结果
  • 常用聚合函数:sum()mean()count()min()max()

数据的分组与聚合

分组与聚合的流程

分组与聚合遵循"拆分-应用-合并"(Split-Apply-Combine)原则:

  1. 拆分(Split):将数据集按照指定标准划分为多个组
  2. 应用(Apply):将聚合函数应用到每个分组
  3. 合并(Combine):将计算结果整合到结果对象中

二、实例详解

实例1:基本分组与聚合

假设我们有一个销售数据集:

产品类别 销售额
A 100
B 200
A 300
B 400
A 500
B 600

分组操作:按"产品类别"分组

python 复制代码
import pandas as pd

data = {
    '产品类别': ['A', 'B', 'A', 'B', 'A', 'B'],
    '销售额': [100, 200, 300, 400, 500, 600]
}
df = pd.DataFrame(data)

# 按产品类别分组
grouped = df.groupby('产品类别')

聚合操作:计算每个产品类别的平均销售额

python 复制代码
# 计算平均销售额
average_sales = grouped['销售额'].mean()
print(average_sales)

输出

复制代码
产品类别
A    300.0
B    400.0
Name: 销售额, dtype: float64

解释

  • 产品类别A的销售额:100, 300, 500 → 平均值 = 300
  • 产品类别B的销售额:200, 400, 600 → 平均值 = 400

实例2:多列分组与多聚合函数

继续使用上面的数据,但这次我们按两个维度分组,并应用多个聚合函数:

python 复制代码
# 创建更复杂的数据集
data = {
    '产品类别': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'],
    '销售月份': ['Jan', 'Jan', 'Feb', 'Feb', 'Jan', 'Jan', 'Feb', 'Feb'],
    '销售额': [100, 200, 300, 400, 500, 600, 700, 800]
}
df = pd.DataFrame(data)

# 按产品类别和销售月份分组
grouped = df.groupby(['产品类别', '销售月份'])

# 应用多个聚合函数
result = grouped['销售额'].agg(['sum', 'mean', 'count'])
print(result)

输出

复制代码
                sum  mean  count
产品类别 销售月份                
A        Jan      600   300      2
         Feb      700   350      2
B        Jan      800   400      2
         Feb      800   400      2

解释

  • 产品类别A在1月的销售额:100 + 500 = 600,平均值300,共2行
  • 产品类别A在2月的销售额:300 + 700 = 1000?(注意:上面示例数据中2月A的销售额是300和700,总和应为1000)
  • 产品类别B在1月的销售额:200 + 600 = 800,平均值400,共2行
  • 产品类别B在2月的销售额:400 + 800 = 1200,平均值600,共2行

实例3:使用agg()进行复杂聚合

python 复制代码
# 定义一个计算极差的函数
def range_value(x):
    return x.max() - x.min()

# 按产品类别分组,应用多个聚合函数
result = df.groupby('产品类别')['销售额'].agg([
    ('总销售额', 'sum'),
    ('平均销售额', 'mean'),
    ('销售额极差', range_value),
    ('产品数量', 'count')
])

print(result)

输出

复制代码
        总销售额  平均销售额  销售额极差  产品数量
产品类别                                
A          1600      400.0        600         4
B          2000      500.0        600         4

解释

  • 产品类别A的总销售额:100+300+500+700 = 1600
  • 产品类别A的平均销售额:400
  • 产品类别A的销售额极差:700-100 = 600
  • 产品类别A共有4个销售记录

数据的排序和排名

Pandas 数据的排序和排名详解

一、数据排序

排序是数据分析中最基础的操作之一,用于将数据按特定顺序排列。Pandas提供了两种主要的排序方法:sort_values()sort_index()

1. sort_values() - 按值排序

这是最常用的排序方法,用于根据列的值进行排序。

基本用法
python 复制代码
# 按单列升序排序
df_sorted = df.sort_values('列名')

# 按单列降序排序
df_sorted_desc = df.sort_values('列名', ascending=False)
多列排序
python 复制代码
# 按多列排序(先按A列升序,再按B列降序)
df_sorted_multi = df.sort_values(by=['A', 'B'], ascending=[True, False])

示例

python 复制代码
import pandas as pd

data = {
    '姓名': ['张三', '李四', '王五', '赵六'],
    '年龄': [25, 30, 35, 40],
    '成绩': [85, 90, 75, 95]
}
df = pd.DataFrame(data)

# 按成绩降序排序
sorted_df = df.sort_values('成绩', ascending=False)
print(sorted_df)

输出

复制代码
   姓名  年龄  成绩
1  李四  30   90
3  赵六  40   95
0  张三  25   85
2  王五  35   75

2. sort_index() - 按索引排序

用于根据索引标签进行排序。

基本用法
python 复制代码
# 按行索引升序排序
df_sorted = df.sort_index()

# 按行索引降序排序
df_sorted_desc = df.sort_index(ascending=False)

# 按列索引排序
df_sorted_cols = df.sort_index(axis=1)

示例

python 复制代码
# 创建带自定义索引的DataFrame
df = pd.DataFrame(
    {'A': [3, 1, 2], 'B': [5, 2, 4]},
    index=['c', 'a', 'b']
)

# 按行索引升序排序
print(df.sort_index())
# 按行索引降序排序
print(df.sort_index(ascending=False))
# 按列索引排序
print(df.sort_index(axis=1))

输出

复制代码
   A  B
a  1  2
b  2  4
c  3  5

   A  B
c  3  5
b  2  4
a  1  2

   B  A
c  5  3
a  2  1
b  4  2

二、数据排名

排名用于为数据分配排名(从1开始,一直到有效数据的数量),与排序密切相关。

1. rank() - 排名方法

python 复制代码
# 为指定列进行排名
df['排名'] = df['列名'].rank()
rank()的常用参数
参数 说明 默认值
method 排名方法 'average'
ascending 是否升序排名 True
na_option NA值处理方式 'keep'

2. rank()的5种排名方法详解

(1) average(默认)- 平均排名

相同值取平均排名

示例

python 复制代码
data = {'姓名': ['张三', '李四', '王五', '赵六'], '英语': [90, 83, 70, 83]}
df = pd.DataFrame(data)

df['平均排名'] = df['英语'].rank(method='average', ascending=False)
print(df)

输出

复制代码
   姓名  英语  平均排名
0  张三  90      1.0
1  李四  83      2.5
2  王五  70      4.0
3  赵六  83      2.5

解释

  • 90分排名第1
  • 两个83分并列,它们应该占据第2和第3名,所以取平均值(2+3)/2=2.5
  • 70分排名第4
(2) min - 最小排名

相同值取最小排名

示例

python 复制代码
df['最小排名'] = df['英语'].rank(method='min', ascending=False)
print(df)

输出

复制代码
   姓名  英语  平均排名  最小排名
0  张三  90      1.0        1
1  李四  83      2.5        2
2  王五  70      4.0        4
3  赵六  83      2.5        2

解释

  • 90分排名第1
  • 两个83分都取较小的排名值2
  • 70分排名第4
(3) max - 最大排名

相同值取最大排名

示例

python 复制代码
df['最大排名'] = df['英语'].rank(method='max', ascending=False)
print(df)

输出

复制代码
   姓名  英语  平均排名  最小排名  最大排名
0  张三  90      1.0        1        1
1  李四  83      2.5        2        3
2  王五  70      4.0        4        4
3  赵六  83      2.5        2        3

解释

  • 90分排名第1
  • 两个83分都取较大的排名值3
  • 70分排名第4
(4) first - 按出现顺序

按数据在原始数据中的出现顺序决定排名

示例

python 复制代码
df['顺序排名'] = df['英语'].rank(method='first', ascending=False)
print(df)

输出

复制代码
   姓名  英语  平均排名  最小排名  最大排名  顺序排名
0  张三  90      1.0        1        1        1
1  李四  83      2.5        2        3        2
2  王五  70      4.0        4        4        4
3  赵六  83      2.5        2        3        3

解释

  • 90分排名第1
  • 先出现的李四(83分)排名2
  • 后出现的赵六(83分)排名3
  • 70分排名第4
(5) dense - 密集排名

相同值取相同排名,不跳过后续排名

示例

python 复制代码
df['密集排名'] = df['英语'].rank(method='dense', ascending=False)
print(df)

输出

复制代码
   姓名  英语  平均排名  最小排名  最大排名  顺序排名  密集排名
0  张三  90      1.0        1        1        1        1
1  李四  83      2.5        2        3        2        2
2  王五  70      4.0        4        4        4        3
3  赵六  83      2.5        2        3        3        2

解释

  • 90分排名第1
  • 两个83分都排名2
  • 70分排名3(不跳过数字)

3. 排名方法对比

姓名 英语 average min max first dense
张三 90 1 1 1 1 1
李四 83 2.5 2 3 2 2
赵六 83 2.5 2 3 3 2
王五 70 4 4 4 4 3

三、实际应用案例

案例1:销售数据分析

python 复制代码
import pandas as pd

# 创建销售数据
sales_data = {
    '产品': ['A', 'B', 'C', 'D', 'E'],
    '销售额': [12000, 15000, 10000, 18000, 13000]
}
sales_df = pd.DataFrame(sales_data)

# 按销售额降序排序
sales_sorted = sales_df.sort_values('销售额', ascending=False)

# 计算销售额排名(使用平均排名)
sales_sorted['排名'] = sales_sorted['销售额'].rank(method='average', ascending=False)

print("销售数据排序与排名:")
print(sales_sorted)

输出

复制代码
   产品  销售额  排名
3    D  18000  1.0
1    B  15000  2.0
4    E  13000  3.0
0    A  12000  4.0
2    C  10000  5.0

案例2:学生成绩分析

python 复制代码
import pandas as pd

# 创建学生数据
students = {
    '姓名': ['张三', '李四', '王五', '赵六', '钱七', '孙八'],
    '语文': [85, 90, 75, 80, 88, 92],
    '数学': [90, 85, 88, 92, 80, 85]
}
df = pd.DataFrame(students)

# 按语文成绩降序排序
df_sorted = df.sort_values('语文', ascending=False)

# 计算语文成绩排名
df_sorted['语文排名'] = df_sorted['语文'].rank(method='min', ascending=False)

# 按数学成绩排序并计算排名
df_sorted['数学排名'] = df_sorted['数学'].rank(method='dense', ascending=False)

print("学生语文成绩排名:")
print(df_sorted)

输出

复制代码
   姓名  语文  数学  语文排名  数学排名
1  李四  90  85         1         3
5  孙八  92  85         1         3
4  钱七  88  80         3         5
0  张三  85  90         4         1
3  赵六  80  92         5         2
2  王五  75  88         6         4

四、总结

排序与排名关键点

操作 方法 主要用途 常用参数
按值排序 sort_values() 根据列的值进行排序 by, ascending, inplace
按索引排序 sort_index() 根据索引标签进行排序 axis, ascending, inplace
排名 rank() 为数据分配排名 method, ascending, na_option

结合使用,例如先排序再进行排名,或按特定条件进行多级排序和排名。

时间序列分析

一、时间序列分析的概念与意义

1. 什么是时间序列分析?

时间序列分析是指对按时间顺序排列的数据点进行分析,以发现数据随时间变化的模式、趋势和规律。时间序列数据具有以下核心特征:

  • 时间依赖性:当前观测值与历史观测值存在关联
  • 趋势性:数据随时间呈现上升或下降的长期趋势
  • 季节性:数据在固定周期内重复出现的模式(如月度、季度)
  • 周期性:非固定周期的波动(如经济周期)
  • 随机性:无法预测的随机波动

时间序列数据示例:股票价格、每日气温、网站日访问量、每日销售额、设备传感器读数等

2. 时间序列分析的重要性

时间序列分析在多个领域具有重要价值:

  • 金融领域:股票价格预测、风险评估
  • 物联网:设备健康监测、故障预测
  • 商业智能:销售趋势分析、库存优化
  • 气象学:天气预报、气候研究
  • 制造业:生产过程监控、质量控制

二、Pandas时间序列处理的核心概念

1. Pandas时间类型体系

Pandas构建了完整的时间类型体系,使时间序列处理更加高效:

类型 说明 示例
Timestamp 表示特定时间点(如"2023-01-01 12:00:00") pd.Timestamp('2023-01-01 12:00:00')
Period 表示时间区间(如"2023年1月") pd.Period('2023-01', freq='M')
Timedelta 表示两个时间点之间的差值 pd.Timedelta(days=5, hours=3)
DatetimeIndex 由Timestamp组成的索引,用于时间序列数据 pd.DatetimeIndex(['2023-01-01', '2023-01-02'])

2. 时间序列数据的基本结构

Pandas使用DatetimeIndex作为时间序列数据的核心索引类型,使数据按时间标签高效检索和对齐。

创建时间索引的常用方法

python 复制代码
import pandas as pd

# 生成连续时间索引
dates = pd.date_range(start='2023-01-01', periods=10, freq='D')
print(dates)
# 输出: DatetimeIndex(['2023-01-01', '2023-01-02', ..., '2023-01-10'], dtype='datetime64[ns]', freq='D')

3. 时间频率与偏移量

Pandas支持多种时间频率别名,用于定义时间序列的间隔:

频率别名 含义 示例
D 每日 pd.date_range(start='2023-01-01', periods=10, freq='D')
H 每小时 pd.date_range(start='2023-01-01', periods=24, freq='H')
B 工作日(跳过周末) pd.date_range(start='2023-01-01', periods=10, freq='B')
M 每月最后一天 pd.date_range(start='2023-01-01', periods=12, freq='M')
W 每周 pd.date_range(start='2023-01-01', periods=52, freq='W')
Q 每季度 pd.date_range(start='2023-01-01', periods=4, freq='Q')

三、Pandas时间序列处理的关键操作

1. 设置时间索引

将普通列转换为时间索引

python 复制代码
# 读取含日期字段的数据集
df = pd.read_csv('data.csv')

# 将日期列转换为标准时间格式
df['date'] = pd.to_datetime(df['date'])

# 将日期列设为索引
df = df.set_index('date')

# 或者直接在读取时设置索引
df = pd.read_csv('data.csv', parse_dates=['date'], index_col='date')

2. 重采样(Resampling)

重采样是时间序列分析中最常用的操作之一,用于调整数据的时间频率:

降采样(高频转低频)

python 复制代码
# 将每日数据转换为月度数据(求和)
monthly_data = df.resample('M').sum()

# 将每日数据转换为季度数据(求平均)
quarterly_data = df.resample('Q').mean()

升采样(低频转高频)

python 复制代码
# 将月度数据转换为每日数据(前向填充)
daily_data = df.resample('D').ffill()

# 将月度数据转换为每日数据(线性插值)
daily_data = df.resample('D').interpolate('linear')

重采样示例

python 复制代码
# 创建示例数据
dates = pd.date_range(start='2023-01-01', periods=30, freq='D')
data = pd.Series(range(30), index=dates)

# 降采样为每周(求和)
weekly = data.resample('W').sum()
print("每周总和:\n", weekly)

# 升采样为每小时
hourly = data.resample('H').ffill()
print("\n每小时数据:\n", hourly)

3. 滑动窗口分析

滑动窗口分析能揭示时间序列数据的短期趋势和模式,是异常检测和趋势分析的有力工具。

基本用法

python 复制代码
# 计算7天移动平均
df['7_day_ma'] = df['value'].rolling(window=7).mean()

# 计算30天移动标准差
df['30_day_std'] = df['value'].rolling(window=30).std()

# 计算30天移动相关系数
df['corr'] = df['value'].rolling(window=30).corr(df['other_value'])

高级滑动窗口应用

python 复制代码
# 计算10分钟窗口的振动能量(RMS)
df['vibration_rms'] = df['acceleration'].rolling('10T').apply(lambda x: np.sqrt(np.mean(x**2)))

# 计算24小时移动平均
df['24h_ma'] = df['value'].rolling('24H').mean()

4. 缺失值处理

时间序列数据中缺失值处理需要特殊技巧:

python 复制代码
# 前向填充
df_filled = df.fillna(method='ffill')

# 后向填充
df_filled = df.fillna(method='bfill')

# 线性插值
df_filled = df.interpolate(method='linear')

# 用特定值填充
df_filled = df.fillna(0)

5. 时间特征提取

从时间戳中提取有用特征:

python 复制代码
# 提取年份、月份、星期几等
df['year'] = df.index.year
df['month'] = df.index.month
df['day'] = df.index.day
df['weekday'] = df.index.weekday
df['is_weekend'] = df.index.weekday >= 5

# 提取季度
df['quarter'] = df.index.quarter

# 提取是否为月末
df['is_month_end'] = df.index.is_month_end

实际案例

四、 什么是移动平均

移动平均是一种简单但有效的时间序列平滑技术,通过计算固定窗口内数据的平均值来减少数据波动,帮助我们更清晰地看到数据的整体趋势。

使用Pandas进行移动平均

在Pandas中,我们可以使用rolling()方法配合mean()函数来计算移动平均值。

基本步骤

  1. 确保你的数据有时间索引
  2. 使用rolling(window_size)指定窗口大小
  3. 调用mean()计算平均值

简单示例

python 复制代码
import pandas as pd
import numpy as np

# 创建示例时间序列数据
dates = pd.date_range(start='2023-01-01', periods=10, freq='D')
values = [10, 15, 20, 25, 30, 35, 40, 45, 50, 55]
df = pd.DataFrame({'value': values}, index=dates)

# 计算3天移动平均
df['moving_avg'] = df['value'].rolling(window=3).mean()

print(df)

输出结果

复制代码
            value  moving_avg
2023-01-01     10         NaN
2023-01-02     15         NaN
2023-01-03     20        15.0
2023-01-04     25        20.0
2023-01-05     30        25.0
2023-01-06     35        30.0
2023-01-07     40        35.0
2023-01-08     45        40.0
2023-01-09     50        45.0
2023-01-10     55        50.0

解释

  • 前2个值显示为NaN,因为窗口大小为3,前2个数据点无法形成完整的窗口
  • 从第3个数据点开始,每个移动平均值都是当前点和前2个点的平均值
    • 2023-01-03: (10 + 15 + 20) / 3 = 15
    • 2023-01-04: (15 + 20 + 25) / 3 = 20
    • 以此类推

为什么使用移动平均

  • 平滑数据:减少随机波动,使趋势更明显
  • 识别模式:更容易看出数据的长期趋势
  • 预测基础:为更复杂的预测模型提供基础

常见窗口大小选择

  • 短期分析:窗口大小=5-7天(如股票交易)
  • 中期分析:窗口大小=15-30天(如销售趋势)
  • 长期分析:窗口大小=90-365天(如年度趋势)

注意事项

  1. 窗口大小会影响结果:窗口越大,平滑效果越明显,但可能丢失短期波动
  2. 前几个数据点会显示为NaN,因为没有足够的数据计算平均值
  3. 可以使用min_periods参数控制最少需要多少个数据点才能计算平均值
python 复制代码
# 设置min_periods参数,让前几个数据点也能计算
df['moving_avg'] = df['value'].rolling(window=3, min_periods=1).mean()

一个更简单的例子

python 复制代码
import pandas as pd

# 创建简单数据
data = [10, 15, 20, 25, 30]
df = pd.DataFrame(data, columns=['value'])

# 计算3天移动平均
df['moving_avg'] = df['value'].rolling(window=3).mean()

print(df)

输出

复制代码
   value  moving_avg
0     10         NaN
1     15         NaN
2     20        15.0
3     25        20.0
4     30        25.0
相关推荐
叫我:松哥2 天前
基于scrapy的网易云音乐数据采集与分析设计实现
python·信息可视化·数据分析·beautifulsoup·numpy·pandas
测试摆渡媛2 天前
Excel模板填充工具(工具&脚本分享)
python·数据挖掘·pandas
_Soy_Milk2 天前
【算法工程师】—— Python 数据分析
python·数据分析·numpy·pandas·matplotlib
Data-Miner3 天前
类似Pandas AI的几个数据分析处理智能体介绍
人工智能·数据分析·pandas
智航GIS5 天前
11.18 自定义Pandas扩展开发指南:打造你的专属数据分析武器库
python·数据分析·pandas
人工干智能6 天前
你知道 Pandas 中 `pd.get_dummies()` 会生成哪些独热的新列么?
大数据·pandas
weixin_462446236 天前
Python 实战:将 HTML 表格一键导出为 Excel(xlsx)
linux·python·excel·pandas
2401_841495646 天前
【Python高级编程】学习通签到统计工具
python·pandas·gui·tkinter·pyinstaller·数据统计·exe程序
西红市杰出青年7 天前
Python异步----------await方法逻辑
pandas