Python 数据分析:Pandas Series 零基础入门教程

文章目录


一、Series 简介

Series 是 Pandas 中的 一维带标签数组 ,是 Pandas 两大核心数据结构之一(另一个是二维的 DataFrame)。Series 可理解为 一列数据,由两部分组成:

  • values(值):存储实际数据,可以是数字、字符串、布尔值等,底层基于 NumPy 数组
  • index(索引):数据对应的标签,用来定位元素。索引默认是从 0 开始的整数序列,也可以手动自定义标签

区别:普通 NumPy 一维数组只有位置编号;Series 自带索引标签,既可以用位置取数,也可以用标签取数,这是 Series 最核心的特点。

Series 结构如下:

核心特点如下:

  1. 一维结构:只能存一列,不能多列;多列数据用 DataFrame
  2. 同类型数据:同一 Series 里元素一般是相同数据类型(int/float/string)
  3. 索引独立:索引可以自定义,不一定是 0,1,2;索引可以不连续
  4. 支持向量化运算:不用写循环,整列直接加减运算,继承 NumPy 优势
  5. 自带丰富方法:统计、缺失值处理、切片筛选等

注:DataFrame 的每一列本质上就是一个 Series。

后文演示默认引入 Pandas:import pandas as pd


二、Series 基本语法

2.1 Series 创建

python 复制代码
# series创建
s = pd.Series([1, 2, 3, 4, 5])
# 自定义索引
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
# 自定义name
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'], name='月份')
python 复制代码
# 通过字典的方式创建
s = pd.Series({'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5})
print(s)
s1 = pd.Series(s, index=['a', 'b'])  # s基础上只取ab索引
print(s1)
s1 = pd.Series(s, index=["a", "b", "c"])  # s基础上只取abc索引
print(s1)

2.2 Series 的属性

属性 说明 属性 说明
index Series的索引对象 loc[] 显式索引,按标签索引或切片
values Series的值 iloc[] 隐式索引,按位置索引或切片
dtypedtypes Series的元素类型 at[] 使用标签访问单个元素
shape Series的形状 iat[] 使用位置访问单个元素
ndim Series的维度
size Series的元素个数
name Series的名称

示例代码:

python 复制代码
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'], name='月份')  # 定义name
print(s.index)  # Index(['a', 'b', 'c', 'd', 'e'], dtype='str')
print(s.values)  # [1 2 3 4 5]
print(s.shape)  # (5,)
print(s.ndim)  # 1
print(s.size)  # 5
print(s.dtype, s.dtypes)  # int64 int64
print(s.name)  # 月份
print(s.loc['a'])  # 1,显示索引
print(s.iloc[0])  # 1,隐式索引
print(s.at['a'])  # 1,显示,访问单个元素,不支持切片
print(s.iat[0])  # 1,隐式

注: loc[标签切片]:闭区间 [start, end],包含结束标签;iloc[位置切片]:左闭右开 [start, end),不包含结束位置

python 复制代码
 # 切片
print(s.loc['a':'c'])
# a    1
# b    2
# c    3
# Name: 月份, dtype: int64
print(s.iloc[0:2])
# a    1
# b    2
# Name: 月份, dtype: int64

另外:若传入列表形式 [[x,y,z]],不管 loc 还是 iloc,都是选取指定项,不存在区间问题。

python 复制代码
print(s.loc[['a', 'b']])
# a    1
# b    2
# Name: 月份, dtype: int64
print(s.iloc[[0, 2]])
# a    1
# c    3
# Name: 月份, dtype: int64

2.3 访问数据

python 复制代码
s = pd.Series([1, 2, 3, 4, 5, 6], index=['a', 'b', 'c', 'd', 'e', 'f'], name='月份')
print(s['a'])
print(s[s < 3])  # 布尔索引
# a    1
# b    2
# Name: 月份, dtype: int64
print(s.head())  # 默认前5个
print(s.tail())  # 默认后5个
print(s.head(2))  # 前2个
print(s.tail(1))  # 后1个

2.4 缺失值统一处理

python 复制代码
# 缺失值统一处理
s = pd.Series([10, 2, np.nan, None, 3, 4], index=['a', 'b', 'c', 'd', 'e', 'f'])
print(s)

三、Series 常用函数

方法 说明 方法 说明
head() 查看前 n 行数据,默认 5 行 max() 最大值
tail() 查看后 n 行数据,默认 5 行 var() 方差
isin() 判断元素是否包含在参数集合中 std() 标准差
isna() 判断是否为缺失值(如 NaN 或 None) median() 中位数
sum() 求和,自动忽略缺失值 mode() 众数(可返回多个)
mean() 平均值 quantile(q) 分位数,q 取 0~1 之间
min() 最小值 describe() 常见统计信息(count、mean、std、min、25%、50%、75%、max)

注:mean()sum()std()var()min()max()median() 默认都会自动忽略 NaN(缺失值),不会把 nanNone 参与计算。


示例代码1:

python 复制代码
s = pd.Series([1, 2, 3, 4, 5, 6], index=['a', 'b', 'c', 'd', 'e', 'f'])
# head()、tail() 默认取5个
print(s.head())
print(s.tail())
print(s.head(2))
print(s.tail(1))

示例代码2:

python 复制代码
s = pd.Series([1, 2, np.nan, None, 5], index=['a', 'b', 'c', 'd', 'e'])
print(s.isna())  # 检查series中元素是否为缺失值
print(s.isin([5]))  # 检查元素 5 是否在集合里
s.isin([1, 5])   # 检查 1、5 元素是否在集合里

示例代码3:

python 复制代码
s = pd.Series([1, 2, 3, 4, 5, np.nan], index=['a', 'b', 'c', 'd', 'e', 'f'])
print(s.mean())  # 3.0 平均值
print(s.sum())   # 15.0 总和,不包含nan
print(s.std())   # 1.5811388300841898 标准差
print(s.var())   # 2.5 方差
print(s.min())   # 1.0 最小值
print(s.max())   # 5.0 最大值
print(s.median())  # 3.0 中位数
print(s.mode())  # 众数
print(s.quantile(0.25))  # 2.0分位数

# 查看所有描述性信息
s.describe()

注:计算分位数时,Pandas 内部会先对 Series 的有效值自动排序,再计算对应分位数。并且默认自动忽略 NanNone


方法 说明 方法 说明
value_counts() 每个唯一值的出现次数 sort_values() 按值排序
count() 非缺失值数量 replace() 替换值
nunique() 唯一值个数(去重) keys() 返回 Series 的索引对象
unique() 获取去重后的值数组
drop_duplicates() 去除重复项
sample() 随机抽样
sort_index() 按索引排序

示例代码4:

python 复制代码
# 众数:出现最多次数的数
s = pd.Series([1, 2, 4, 4, 3], index=['a', 'b', 'c', 'd', 'e'])
print(s.sort_values())  # 排序,缺失值放在后面
print(s.sort_index(ascending=False))  # 按照索引排序

注:ascending 代表升序的意思


示例代码5:

python 复制代码
s = pd.Series([1, 2, 2, 4, 5, np.nan], index=['d','b','a','c','f','e'], name='data')

print(s.value_counts())  # 统计每个值出现次数
print(s.count())         # 5 非缺失值数量
print(s.replace(2, 99))  # 替换值
print(s.nunique())       # 4 唯一值个数(去重)
# 获取索引
print(s.keys())          # 方法
print(s.index)   	     # 属性 结果同上
# Index(['d', 'b', 'a', 'c', 'f', 'e'], dtype='str')

print(s.unique())        # 获取去重后的值数组
# [ 1.  2.  4.  5. nan]

print(s.drop_duplicates())  # 删除重复项
print(s.sample(2))          # 随机抽样

四、Series 案例

题目1:学生成绩统计

python 复制代码
"""
题目1:学生成绩统计
创建一个包含10名学生数学成绩的Series,成绩范围在50-100之间。
计算平均分、最高分、最低分,并找出高于平均分的学生人数。
"""
import pandas as pd
import numpy as np

np.random.seed(42)  # 设置随机种子
values = np.random.randint(50, 101, 10)
index = []
for i in range(1, 11):
    index.append('学生' + str(i))
scores = pd.Series(values, index)
print(scores)

print('平均分:', scores.mean())
print('最高分:', scores.max())
print('最低分:', scores.min())
mean_score = scores.mean()
print('高于平均分的学生人数:', len(scores[scores >= mean_score]))  # 布尔索引

题目2:温度数据分析

python 复制代码
'''
题目2:温度数据分析
给定某城市一周每天的最高温度Series,完成以下任务:
- 找出温度超过30度的天数
- 计算平均温度
- 将温度从高到低排序
- 找出温度变化最大的两天
'''
import pandas as pd
import numpy as np

temperatures = pd.Series([28, 31, 29, 32, 30, 27, 33], index=['周一', '周二', '周三', '周四', '周五', '周六', '周日'])

print('温度超过30度的天数:', len(temperatures[temperatures > 30]))
print('温度超过30度的天数:', temperatures[temperatures > 30].count())
print('温度超过30度的天数:', temperatures[temperatures > 30].size)

print('平均温度:', temperatures.mean())
print('将温度从高到低排序:')
print(temperatures.sort_values(ascending=False))  # ascending:升序
print('-------------------')

temp_diff = temperatures.diff()  # 计算series数组的变化的值
# print(temp_diff)
# 周一    NaN
# 周二    3.0
# 周三   -2.0
# 周四    3.0
# 周五   -2.0
# 周六   -3.0
# 周日    6.0
temp_diff_sort = temp_diff.abs().sort_values(ascending=True)  # 温度变化值排序
print('温度变化最大的两天:', temp_diff_sort.index[0], temp_diff_sort.index[1])
print('温度变化最大的两天:', temp_diff_sort.keys()[0:2].tolist())
# 温度变化最大的两天: ['周三', '周五']

注:diff() 用于计算和上一个数据的变化差值


题目3:股票价格分析

python 复制代码
'''
题目3:股票价格分析
给定某股票连续10个交易日的收盘价Series:
- 计算每日收益率(当日收盘价/前日收盘价-1)
- 找出收益率最高和最低的日期
- 计算波动率(收益率的标准差)
'''
import pandas as pd
import numpy as np

values = np.array([102.3, 103.5, 105.1, 104.8, 106.2, 107.0, 106.5, 108.1, 109.3, 110.2])
index = pd.date_range('2023-01-01', periods=10)
prices = pd.Series(values, index)
print(prices)
# 2023-01-01    102.3
# 2023-01-02    103.5
# 2023-01-03    105.1
# ...
print('-----------------------')
yields = prices.pct_change()  # 103.5/102.3-1
print('每日收益率:')
print(yields)
print('-----------------------')
print('收益率最高日期:', yields.idxmax())  # max()最大值,idxmax() 最大值的索引
print('收益率最低日期:', yields.idxmin())
print('波动率', yields.std())

注:

  • pct_change() 可计算收益率(计算公式:当日收盘价/前日收盘价-1);idxmax() 用于最大值的索引,idxmin() 同理
  • periods表示生成多少个时间点。如:periods=10 表示创建 10 条日期。
  • 没有写freq时,默认 freq='D',也就是按天生成。

题目4:销售数据分析

python 复制代码
'''
题目4:销售数据分析
某产品过去12个月的销售量
- 计算季度平均销量(每3个月为一个季度)
- 找出销量最高的月份
- 计算月环比增长率
- 找出连续增长超过2个月的月份
'''
import pandas as pd
import numpy as np

values = np.array([120, 135, 145, 160, 155, 170, 180, 175, 190, 200, 210, 220])
index = pd.date_range('2022-01-01', periods=12, freq='MS')  
# freq='MS' 频率按照月生成,MS代表每个月开始,D代表天为频率
sales = pd.Series(values, index)
print(sales)
print('-----------------------')
print('季度平均销量:')
print(sales.resample('QS').mean())  # 按照季度重新采样,(120+135+145)/3
print('-----------------------')
print('销量最高的月份:', sales.idxmax())
print('计算月环比增长率:')
print(sales.pct_change())
print('-----------------------')

# sales.pct_change() > 0 # 检查连续3个是true的窗口
sales_rolling = (sales.pct_change() > 0).rolling(window=3)  # 大小为3的窗口
sales_rolling_sum = sales_rolling.sum()  # 窗口加和, True 等价于 1,False 等价于 0
print(sales_rolling_sum)
# 2022-01-01    NaN
# 2022-02-01    NaN
# 2022-03-01    2.0
# 2022-04-01    3.0
# 2022-05-01    2.0
# 2022-06-01    2.0
#...
print(sales_rolling_sum[sales_rolling_sum >= 3].keys().tolist())
# [Timestamp('2022-04-01 00:00:00'), Timestamp('2022-11-01 00:00:00'), Timestamp('2022-12-01 00:00:00')]
  • freq 取值频率:

    D:按天

    MS:MonthStart,每月月初

    ME:MonthEnd,每月月末

    YS:YearStart,每年年初

    YE:YearEnd,每年年末

  • resample()时间序列重采样 ,可对当前序列,重新按照制定规则取样。如:QS 表示把高频时间数据(这里是月度)聚合为低频数据季度 。

    D:按天

    W:按周(默认周日结束)

    MS:每月月初

    ME:每月月末

    QS:季度初

    QE:季度末

    YS:每年年初

    YE:每年年末

    H:小时

    T:分钟

  • rolling(window=N)滚动窗口 。在序列上开一个固定大小的窗口,窗口沿着数据从上到下滑动,每次滑动一格。可对窗口内的数据执行聚合计算(sum /mean/max 等)。

    如:window=3:窗口大小为 3,每次取当前位置 + 前面 2 个 ,一共 3 条数据。若不足窗口长度的位置,默认返回 NaN


题目5:每小时销售数据分析

python 复制代码
'''
题目5:每小时销售数据分析
某商店每小时销售额
- 按天重采样计算每日总销售额
- 计算每天营业时间(8:00-22:00)和非营业时间的销售额比例
- 找出销售额最高的3个小时
'''
import pandas as pd
import numpy as np

np.random.seed(42)  # 设置随机种子
values = np.random.randint(0, 100, 24)
index = pd.date_range('2025-01-01', periods=24, freq='h')
hours_sales = pd.Series(values, index)
# 2025-01-01 00:00:00    51
# 2025-01-01 01:00:00    92
# 2025-01-01 02:00:00    14
# 2025-01-01 03:00:00    71
# ...

# 按天重采样计算每日总销售额
day_sales = hours_sales.resample('D')
print(day_sales.sum())  # 或者 hours_sales.sum()

# 计算每天营业时间(8:00-22:00)和非营业时间的销售额比例

# 法1:使用between_time函数筛选一段时间的series
business_hours_sales = hours_sales.between_time('8:00', '22:00')
print(business_hours_sales.sum() / (day_sales.sum() - business_hours_sales.sum()))

# 法2:利用布尔索引
business_hours_sales = hours_sales[(hours_sales.index.hour >= 8) & (hours_sales.index.hour <= 22)]
print(business_hours_sales.sum() / (day_sales.sum() - business_hours_sales.sum()))

# 法3:也可利用drop去除营业时间段的销售
not_business_hours_sales = hours_sales.drop(business_hours_sales.index)
print(business_hours_sales.sum() / not_business_hours_sales.sum())

# 找出销售额最高的3个小时
print(hours_sales.nlargest(3).keys())
  • between_time(start_time, end_time):时间索引专用,筛选同一天内 指定时段,包含起止时刻
  • nlargest(n):取出数值最大 n 条,返回 Series,可使用.index/.keys()拿到对应索引。
  • drop(索引):删掉指定索引对应的行,返回删掉之后新的 Series。

注:between_time('8:00','22:00'):只看时间(小时分钟),忽略日期,即:不管是哪一天,只要时间落在 8:00~22:00 就筛选出来。


参考链接:Python数据分析教程,零基础学会numpy+pandas+matplotlib数据分析,数据可视化

相关推荐
心易行者42 分钟前
Python在线运行+SQLite数据库实战:0成本搭个人数据后台,5个场景直接套用
前端·网络·人工智能·python
数据杂坛1 小时前
【Python程序开发系列】实例方法、类方法(@classmethod)、静态方法(@staticmethod)有什么区别
python·课程设计·python语法
正经教主1 小时前
【FDE系列】阶段2:Day 31:SQL 基础 — 增删改查一把梭
人工智能·python·fde
leihefeng1 小时前
PX04-用 Python 读 Excel 画折线图,还能直接插回 Excel 文件
python·excel
Mr.朱鹏2 小时前
Docker三剑客实战指南:Docker、Dockerfile 和 Docker Compose
python·docker·devops·dockerfile
0566462 小时前
用大模型构建答疑机器人:从 API 调用到上下文工程
python·学习·agent
haluhalu.2 小时前
初识 Protobuf:微服务跨语言通信的一份契约
java·c语言·开发语言·c++·python
Liaiyang662 小时前
# 自研 AST 容错初筛工具:横向评测 Django、PyTorch、TensorFlow 三大开源 Python 框架异常收容风险
python·测试工具·自动化·开源软件·代码规范·devops·代码复审
空奈qwq2 小时前
机器学习入门:从核心概念到建模全流程
人工智能·python·机器学习