第144集:Pandas Series
一、Pandas简介
Pandas是Python中用于数据处理和分析的强大库,它提供了灵活且高效的数据结构,使得数据处理变得简单直观。Pandas的核心数据结构包括:
- Series:一维带标签的数组
- DataFrame:二维带标签的表格数据结构
本集我们将重点学习Pandas Series的基本概念和操作。
二、什么是Series
Series是Pandas中最基本的数据结构之一,它是一个一维带标签的数组,可以存储任意数据类型(整数、浮点数、字符串、布尔值等)。
Series的特点:
- 带标签:每个元素都有一个标签(索引)
- 异质数据:可以包含不同类型的数据
- 强大的索引:支持多种索引方式
- 缺失值处理:内置对缺失值的处理机制
- 丰富的操作:提供大量的统计和数据处理方法
三、创建Series
1. 从列表创建
import pandas as pd
# 从列表创建Series
data = [1, 2, 3, 4, 5]
s = pd.Series(data)
print(s)
# 输出:
# 0 1
# 1 2
# 2 3
# 3 4
# 4 5
# dtype: int642. 指定索引
# 指定索引
index = ['a', 'b', 'c', 'd', 'e']
s = pd.Series(data, index=index)
print(s)
# 输出:
# a 1
# b 2
# c 3
# d 4
# e 5
# dtype: int643. 从字典创建
# 从字典创建Series
data = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
s = pd.Series(data)
print(s)
# 输出:
# a 1
# b 2
# c 3
# d 4
# e 5
# dtype: int644. 从标量值创建
# 从标量值创建Series
s = pd.Series(5, index=['a', 'b', 'c', 'd', 'e'])
print(s)
# 输出:
# a 5
# b 5
# c 5
# d 5
# e 5
# dtype: int645. 从NumPy数组创建
import numpy as np
# 从NumPy数组创建Series
arr = np.array([1, 2, 3, 4, 5])
s = pd.Series(arr)
print(s)
# 输出:
# 0 1
# 1 2
# 2 3
# 3 4
# 4 5
# dtype: int64四、Series的属性
Series具有多种属性,可以帮助我们了解Series的基本信息:
1. values:获取Series的值
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
print(s.values)
# 输出:[1 2 3 4 5]2. index:获取Series的索引
print(s.index)
# 输出:Index(['a', 'b', 'c', 'd', 'e'], dtype='object')3. dtype:获取Series的数据类型
print(s.dtype)
# 输出:int644. shape:获取Series的形状
print(s.shape)
# 输出:(5,)5. size:获取Series的元素数量
print(s.size)
# 输出:56. ndim:获取Series的维度
print(s.ndim)
# 输出:17. empty:检查Series是否为空
print(s.empty)
# 输出:False五、Series的索引和切片
1. 基于标签的索引(标签索引)
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
# 单个标签索引
print(s['a'])
# 输出:1
# 多个标签索引
print(s[['a', 'c', 'e']])
# 输出:
# a 1
# c 3
# e 5
# dtype: int642. 基于位置的索引(位置索引)
# 使用iloc属性进行位置索引
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
# 单个位置索引
print(s.iloc[0])
# 输出:1
# 多个位置索引
print(s.iloc[[0, 2, 4]])
# 输出:
# a 1
# c 3
# e 5
# dtype: int643. 切片操作
# 基于标签的切片(包含end)
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
print(s['a':'c'])
# 输出:
# a 1
# b 2
# c 3
# dtype: int64
# 基于位置的切片(不包含end)
print(s.iloc[0:3])
# 输出:
# a 1
# b 2
# c 3
# dtype: int64六、Series的基本操作
1. 算术运算
Series支持所有基本的算术运算,运算时会自动对齐索引:
s1 = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
s2 = pd.Series([5, 4, 3, 2, 1], index=['a', 'b', 'c', 'd', 'e'])
# 加法
print(s1 + s2)
# 输出:
# a 6
# b 6
# c 6
# d 6
# e 6
# dtype: int64
# 减法
print(s1 - s2)
# 输出:
# a -4
# b -2
# c 0
# d 2
# e 4
# dtype: int64
# 乘法
print(s1 * s2)
# 输出:
# a 5
# b 8
# c 9
# d 8
# e 5
# dtype: int64
# 除法
print(s1 / s2)
# 输出:
# a 0.2
# b 0.5
# c 1.0
# d 2.0
# e 5.0
# dtype: float642. 比较运算
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
print(s > 3)
# 输出:
# a False
# b False
# c False
# d True
# e True
# dtype: bool
print(s == 3)
# 输出:
# a False
# b False
# c True
# d False
# e False
# dtype: bool3. 逻辑运算
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
# 使用&(与)、|(或)、~(非)进行逻辑运算
print((s > 2) & (s < 5))
# 输出:
# a False
# b False
# c True
# d True
# e False
# dtype: bool
print((s < 2) | (s > 4))
# 输出:
# a True
# b False
# c False
# d False
# e True
# dtype: bool七、Series的统计功能
Pandas Series提供了丰富的统计方法:
1. 基本统计量
s = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(f"求和:{s.sum()}")
print(f"平均值:{s.mean()}")
print(f"中位数:{s.median()}")
print(f"最大值:{s.max()}")
print(f"最小值:{s.min()}")
print(f"标准差:{s.std()}")
print(f"方差:{s.var()}")
print(f"计数:{s.count()}")
print(f"25%分位数:{s.quantile(0.25)}")
print(f"50%分位数:{s.quantile(0.5)}")
print(f"75%分位数:{s.quantile(0.75)}")
# 输出:
# 求和:55
# 平均值:5.5
# 中位数:5.5
# 最大值:10
# 最小值:1
# 标准差:3.0276503540974917
# 方差:9.166666666666666
# 计数:10
# 25%分位数:3.25
# 50%分位数:5.5
# 75%分位数:7.752. 累计统计
s = pd.Series([1, 2, 3, 4, 5])
print(f"累计和:{s.cumsum()}")
print(f"累计积:{s.cumprod()}")
print(f"累计最大值:{s.cummax()}")
print(f"累计最小值:{s.cummin()}")
# 输出:
# 累计和:0 1
# 1 3
# 2 6
# 3 10
# 4 15
# dtype: int64
# 累计积:0 1
# 1 2
# 2 6
# 3 24
# 4 120
# dtype: int64
# 累计最大值:0 1
# 1 2
# 2 3
# 3 4
# 4 5
# dtype: int64
# 累计最小值:0 1
# 1 1
# 2 1
# 3 1
# 4 1
# dtype: int643. 描述性统计
s = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(s.describe())
# 输出:
# count 10.000000
# mean 5.500000
# std 3.027650
# min 1.000000
# 25% 3.250000
# 50% 5.500000
# 75% 7.750000
# max 10.000000
# dtype: float64八、Series的缺失值处理
在实际数据中,经常会遇到缺失值。Pandas提供了处理缺失值的方法:
1. 检查缺失值
s = pd.Series([1, 2, None, 4, 5, None], index=['a', 'b', 'c', 'd', 'e', 'f'])
print(s.isnull())
# 输出:
# a False
# b False
# c True
# d False
# e False
# f True
# dtype: bool
print(s.notnull())
# 输出:
# a True
# b True
# c False
# d True
# e True
# f False
# dtype: bool2. 过滤缺失值
# 使用dropna()方法过滤缺失值
print(s.dropna())
# 输出:
# a 1.0
# b 2.0
# d 4.0
# e 5.0
# dtype: float64
# 使用布尔索引过滤缺失值
print(s[s.notnull()])
# 输出:
# a 1.0
# b 2.0
# d 4.0
# e 5.0
# dtype: float643. 填充缺失值
# 使用fillna()方法填充缺失值
# 用固定值填充
print(s.fillna(0))
# 输出:
# a 1.0
# b 2.0
# c 0.0
# d 4.0
# e 5.0
# f 0.0
# dtype: float64
# 用前一个值填充(向前填充)
print(s.fillna(method='ffill'))
# 输出:
# a 1.0
# b 2.0
# c 2.0
# d 4.0
# e 5.0
# f 5.0
# dtype: float64
# 用后一个值填充(向后填充)
print(s.fillna(method='bfill'))
# 输出:
# a 1.0
# b 2.0
# c 4.0
# d 4.0
# e 5.0
# f NaN
# dtype: float64
# 用平均值填充
print(s.fillna(s.mean()))
# 输出:
# a 1.0
# b 2.0
# c 3.0
# d 4.0
# e 5.0
# f 3.0
# dtype: float64九、Series的其他操作
1. 修改索引
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
# 直接修改索引
new_index = ['A', 'B', 'C', 'D', 'E']
s.index = new_index
print(s)
# 输出:
# A 1
# B 2
# C 3
# D 4
# E 5
# dtype: int64
# 使用rename()方法修改索引
# 可以传入一个字典来部分修改索引
s = s.rename({'A': 'a', 'B': 'b'})
print(s)
# 输出:
# a 1
# b 2
# C 3
# D 4
# E 5
# dtype: int642. 排序
s = pd.Series([3, 1, 4, 1, 5, 9, 2, 6], index=['c', 'a', 'd', 'a', 'e', 'i', 'b', 'f'])
# 按值排序
print(s.sort_values())
# 输出:
# a 1
# a 1
# b 2
# c 3
# d 4
# e 5
# f 6
# i 9
# dtype: int64
# 按索引排序
print(s.sort_index())
# 输出:
# a 1
# a 1
# b 2
# c 3
# d 4
# e 5
# f 6
# i 9
# dtype: int643. 唯一值
s = pd.Series([1, 2, 2, 3, 3, 3, 4, 4, 4, 4])
print(s.unique())
# 输出:[1 2 3 4]
print(s.nunique())
# 输出:4
# 计算每个值的出现次数
print(s.value_counts())
# 输出:
# 4 4
# 3 3
# 2 2
# 1 1
# dtype: int644. 应用函数
s = pd.Series([1, 2, 3, 4, 5])
# 使用apply()方法应用函数
doubled = s.apply(lambda x: x * 2)
print(doubled)
# 输出:
# 0 2
# 1 4
# 2 6
# 3 8
# 4 10
# dtype: int64
# 使用map()方法映射值
mapped = s.map({1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five'})
print(mapped)
# 输出:
# 0 one
# 1 two
# 2 three
# 3 four
# 4 five
# dtype: object十、案例分析:销售数据统计
问题描述
假设有一个商店的月度销售数据,包含12个月的销售额(单位:万元):
| 月份 | 销售额 |
|---|---|
| 一月 | 25 |
| 二月 | 30 |
| 三月 | 35 |
| 四月 | 28 |
| 五月 | 32 |
| 六月 | 36 |
| 七月 | 38 |
| 八月 | 34 |
| 九月 | 40 |
| 十月 | 42 |
| 十一月 | 45 |
| 十二月 | 50 |
请使用Pandas Series分析这些数据:
- 计算年度总销售额
- 计算月平均销售额
- 找出销售额最高和最低的月份
- 计算销售额超过35万元的月份
- 计算销售额的标准差
解决方案
import pandas as pd
# 创建销售数据Series
months = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
sales = [25, 30, 35, 28, 32, 36, 38, 34, 40, 42, 45, 50]
sales_series = pd.Series(sales, index=months)
print("月度销售数据:")
print(sales_series)
print()
# 1. 年度总销售额
total_sales = sales_series.sum()
print(f"1. 年度总销售额:{total_sales}万元")
# 2. 月平均销售额
avg_sales = sales_series.mean()
print(f"2. 月平均销售额:{avg_sales:.2f}万元")
# 3. 销售额最高和最低的月份
highest_month = sales_series.idxmax()
highest_sales = sales_series.max()
lowest_month = sales_series.idxmin()
lowest_sales = sales_series.min()
print(f"3. 销售额最高的月份:{highest_month},销售额:{highest_sales}万元")
print(f" 销售额最低的月份:{lowest_month},销售额:{lowest_sales}万元")
# 4. 销售额超过35万元的月份
high_sales_months = sales_series[sales_series > 35]
print(f"4. 销售额超过35万元的月份:")
print(high_sales_months)
# 5. 销售额的标准差
std_sales = sales_series.std()
print(f"5. 销售额的标准差:{std_sales:.2f}万元")
# 6. 计算月度销售额的增长率
print(f"6. 月度销售额增长率:")
growth_rate = sales_series.pct_change() * 100
print(growth_rate.round(2))输出结果
月度销售数据:
一月 25
二月 30
三月 35
四月 28
五月 32
六月 36
七月 38
八月 34
九月 40
十月 42
十一月 45
十二月 50
dtype: int64
1. 年度总销售额:435万元
2. 月平均销售额:36.25万元
3. 销售额最高的月份:十二月,销售额:50万元
销售额最低的月份:一月,销售额:25万元
4. 销售额超过35万元的月份:
六月 36
七月 38
九月 40
十月 42
十一月 45
十二月 50
dtype: int64
5. 销售额的标准差:7.33万元
6. 月度销售额增长率:
一月 NaN
二月 20.00
三月 16.67
四月 -20.00
五月 14.29
六月 12.50
七月 5.56
八月 -10.53
九月 17.65
十月 5.00
十一月 7.14
十二月 11.11
dtype: float64十一、总结
本节课我们学习了Pandas Series的基本概念和操作:
- Series的创建:从列表、字典、标量、NumPy数组等创建Series
- Series的属性:values、index、dtype、shape、size等
- Series的索引和切片:基于标签和位置的索引方式
- Series的基本操作:算术运算、比较运算、逻辑运算
- Series的统计功能:求和、平均值、中位数、标准差等
- Series的缺失值处理:检查、过滤、填充缺失值
- Series的其他操作:修改索引、排序、唯一值、应用函数
- 实际应用案例:销售数据统计分析
Series是Pandas的基础数据结构,掌握Series的操作对于学习Pandas DataFrame和数据分析非常重要。下一节课,我们将学习Pandas的另一个核心数据结构——DataFrame。
十二、练习
创建一个Series,包含10个随机整数(范围1-100),并使用字母作为索引
对上述Series进行以下操作:
- 计算最大值、最小值、平均值和标准差
- 找出大于50的值
- 按值降序排序
- 计算累计和
创建一个包含缺失值的Series,并进行以下操作:
- 检查缺失值
- 使用前一个值填充缺失值
- 使用平均值填充缺失值
假设有一周的天气数据(摄氏度):
- 周一:22
- 周二:25
- 周三:23
- 周四:24
- 周五:26
- 周六:28
- 周日:27
使用Series分析这些数据:
- 计算平均温度
- 找出最高温度的日期
- 计算温度的变化率
- 将温度转换为华氏度(华氏度 = 摄氏度 × 9/5 + 32)
扩展阅读
- Pandas官方文档:https://pandas.pydata.org/docs/
- Pandas Series教程:https://pandas.pydata.org/docs/user_guide/10min.html#series
- Pandas缺失值处理:https://pandas.pydata.org/docs/user_guide/missing_data.html