一聚教程网:一个值得你收藏的教程网站

热门教程

Pandas中Series序列的实现原理

时间:2026-05-28 18:30:01 编辑:袖梨 来源:一聚教程网

Pandas库中的Series数据结构专为处理一维带标签数据而设计,相比NumPy数组具有更丰富的功能和灵活性。

一、Series 的核心定义

Series 是 Pandas 专为一维数据设计的结构,对比 NumPy 一维数组,核心差异是:

Pandas中Series序列的具体实现

表格

特性Pandas SeriesNumPy 一维数组
索引支持自定义标签(字符串 / 数字 / 时间等)仅支持整数位置索引
数据类型可混合类型(如同时存 int/str)仅支持同一种数据类型
缺失值原生支持 NaN,内置缺失值处理方法需手动处理 NaN
功能内置统计 / 对齐 / 可视化等方法仅基础数值计算

直观理解:把 Series 想象成 "带列名的一列数据",由两部分组成:

  1. values:数据本身(底层是 NumPy 数组);
  2. index:自定义标签(索引),和数据一一对应。

二、创建 Series(核心语法)

创建 Series 的核心函数是 pd.Series(),最常用的 4 种方式如下:

1. 从列表 / 数组创建(基础)

import pandas as pd
import numpy as np
# 方式1:从列表创建(默认整数索引 0,1,2...)
scores = [85, 92, 78, 90, 88]
s1 = pd.Series(scores)
print("从列表创建的Series:")
print(s1)
# 方式2:指定自定义索引
names = ["小明", "小红", "小刚", "小丽", "小强"]
s2 = pd.Series(scores, index=names)
print("n指定索引的Series:")
print(s2)
# 方式3:从NumPy数组创建
arr = np.array([15.2, 16.1, 14.8, 15.5])
s3 = pd.Series(arr, index=["1月", "2月", "3月", "4月"], name="月均温度")
print("n带名称的Series:")
print(s3)

输出:

从列表创建的Series:

0 85

1 92

2 78

3 90

4 88

dtype: int64

指定索引的Series:

小明 85

小红 92

小刚 78

小丽 90

小强 88

dtype: int64

带名称的Series:

1月 15.2

2月 16.1

3月 14.8

4月 15.5

Name: 月均温度, dtype: float64

2. 从字典创建(索引 = 字典 key,值 = 字典 value)

import pandas as pd
# 字典:键=姓名,值=分数
score_dict = {"小明":85, "小红":92, "小刚":78, "小丽":90}
s4 = pd.Series(score_dict)
print("从字典创建的Series:")
print(s4)

输出

从字典创建的Series:

小明 85

小红 92

小刚 78

小丽 90

dtype: int64

3. 创建含缺失值的 Series

import pandas as pd
import numpy as np
# 含NaN的Series(缺失值)
s5 = pd.Series([85, np.nan, 92, 78, np.nan], index=["小明", "小红", "小刚", "小丽", "小强"])
print("含缺失值的Series:")
print(s5)

输出

含缺失值的Series:

小明 85.0

小红 NaN

小刚 92.0

小丽 78.0

小强 NaN

dtype: float64

三、Series 的核心操作(索引 / 切片)

Series 支持两种索引方式:标签索引(自定义 index)和位置索引(整数位置),这是和 NumPy 数组的核心区别。

1. 标签索引(最常用)

通过自定义索引取值 / 赋值:

import pandas as pd
s = pd.Series([85, 92, 78, 90], index=["小明", "小红", "小刚", "小丽"])
# 取值:通过标签
print("小红的分数:", s["小红"])  # 92
# 赋值:通过标签
s["小刚"] = 80
print("n修改小刚分数后:")
print(s)
# 多标签取值(返回新Series)
print("n小明和小丽的分数:")
print(s[["小明", "小丽"]])

输出

小红的分数: 92

修改小刚分数后:

小明 85

小红 92

小刚 80

小丽 90

dtype: int64

小明和小丽的分数:

小明 85

小丽 90

dtype: int64

2. 位置索引(和 NumPy 一致)

通过整数位置(0 开始)取值,可用 iloc 明确指定位置索引(推荐,避免歧义):

import pandas as pd
s = pd.Series([85, 92, 78, 90], index=["小明", "小红", "小刚", "小丽"])
# 直接用整数(简易写法)
print("第2个元素(位置1):", s[1])  # 92
# 用iloc(明确位置索引,推荐)
print("第4个元素(位置3):", s.iloc[3])  # 90
# 位置切片
print("n位置0-2的元素:")
print(s.iloc[0:3])

输出:

第2个元素(位置1): 92

第4个元素(位置3): 90

位置0-2的元素:

小明 85

小红 92

小刚 78

dtype: int64

3. 布尔索引(筛选数据)

和 NumPy 类似,通过布尔条件筛选元素:

import pandas as pd
s = pd.Series([85, 92, 78, 90, 88], index=["小明", "小红", "小刚", "小丽", "小强"])
# 筛选分数≥90的元素
high_score = s[s >= 90]
print("90分以上的学生:")
print(high_score)
# 筛选分数在80-90之间的元素
mid_score = s[(s >= 80) & (s < 90)]
print("n80-90分的学生:")
print(mid_score)

输出:

90分以上的学生:

小红 92

小丽 90

dtype: int64

80-90分的学生:

小明 85

小强 88

dtype: int64

四、Series 的核心属性与方法

1. 核心属性(快速查看数据特征)

表格

属性作用示例
values返回底层 NumPy 数组s.values → array([85,92,78,90])
index返回索引对象s.index → Index ([' 小明 ',' 小红 ',' 小刚 ',' 小丽 '], dtype='object')
dtype返回数据类型s.dtype → int64
shape返回形状(一维元组)s.shape → (4,)
name返回 Series 名称s.name → ' 分数'
isnull()返回布尔 Series(NaN 为 True)s.isnull() → 小红:True, 小强:True
notnull()返回布尔 Series(非 NaN 为 True)s.notnull() → 小明:True, 小红:False

运行

import pandas as pd
import numpy as np
s = pd.Series([85, np.nan, 92, 78], index=["小明", "小红", "小刚", "小丽"], name="分数")
print("底层数组:", s.values)
print("索引:", s.index)
print("数据类型:", s.dtype)
print("形状:", s.shape)
print("名称:", s.name)
print("缺失值判断:")
print(s.isnull())

输出:

底层数组: [85. nan 92. 78.]

索引: Index(['小明', '小红', '小刚', '小丽'], dtype='object')

数据类型: float64

形状: (4,)

名称: 分数

缺失值判断:

小明 False

小红 True

小刚 False

小丽 False

dtype: bool

2. 常用方法(统计 / 缺失值 / 排序)

(1)统计方法(和 NumPy 类似,但更友好)

import pandas as pd
import numpy as np
s = pd.Series([85, np.nan, 92, 78, 90], index=["小明", "小红", "小刚", "小丽", "小强"])
# 基础统计
print("均值(自动忽略NaN):", s.mean())  # 86.25
print("中位数:", s.median())            # 87.5
print("最大值/最小值:", s.max(), "/", s.min())  # 92 / 78
print("标准差:", s.std())              # 6.18...
# 描述性统计(一键生成)
print("n描述性统计:")
print(s.describe())

输出:

均值(自动忽略NaN): 86.25

中位数: 87.5

最大值/最小值: 92.0 / 78.0

标准差: 6.18465843842649

描述性统计:

count 4.000000

mean 86.250000

std 6.184658

min 78.000000

25% 83.250000

50% 87.500000

75% 90.500000

max 92.000000

dtype: float64

(2)缺失值处理

import pandas as pd
import numpy as np
# 模拟学生分数(含缺失值)
scores = pd.Series([85, np.nan, 92, 78, np.nan, 88, 95], 
                   index=["小明", "小红", "小刚", "小丽", "小强", "小芳", "小伟"])
# 步骤1:统计缺失值数量
nan_count = scores.isnull().sum()
print("缺失值数量:", nan_count)
# 步骤2:用中位数填充缺失值
scores_filled = scores.fillna(scores.median())
print("n填充后的分数:")
print(scores_filled)
# 步骤3:筛选优秀学生(≥90)
excellent = scores_filled[scores_filled >= 90]
print("n优秀学生:")
print(excellent)

七、避坑点与最佳实践

1. 核心避坑点

  1. 混淆标签索引和位置索引:当索引是整数时(如 index=[1,2,3]),s[1] 会优先按标签取值,而非位置,建议用 iloc 明确位置索引;
  2. 忽略缺失值:Series 的统计方法(如 mean())会自动忽略 NaN,但如果需要包含 NaN 需手动处理;
  3. 直接修改 Series 索引:index 是不可变对象,需用 s.reset_index() 或 s.set_index() 修改;
  4. 布尔条件组合错误:多条件组合需用 &/|(而非 and/or),且每个条件需用括号包裹。

2. 最佳实践

  1. 索引命名:创建 Series 时给 index 和 name 命名,增强可读性;
  2. 明确索引方式:位置索引用 iloc,标签索引用 loc(s.loc["小红"]),避免歧义;
  3. 缺失值处理:先统计缺失值数量(isnull().sum()),再选择填充 / 删除策略;
  4. 大数据处理:Series 底层是 NumPy 数组,优先用向量化方法(如 map/apply),避免循环。

总结

  1. Series 是 Pandas 一维带标签的数据结构,由 values(数据)和 index(标签)组成,支持混合数据类型和缺失值;
  2. 核心操作:
    1. 索引:标签索引(s["小红"]/s.loc["小红"])、位置索引(s.iloc[1]);
    2. 筛选:布尔索引(s[s>=90]);
    3. 统计:mean()/median()/std()(自动忽略 NaN);
    4. 缺失值:dropna()/fillna();
  3. 核心优势:对比 NumPy 数组,Series 支持自定义标签、缺失值原生处理、丰富的统计 / 清洗方法;
  4. 避坑关键:明确索引方式,处理缺失值,正确组合布尔条件。

作为Pandas的基础数据结构,Series凭借其标签索引、缺失值处理和丰富方法等特性,成为数据分析和处理的核心工具之一。

热门栏目