4. Pandas数据结构:Series与DataFrame的创建、索引与切片、数据筛选与排序

各位工程师朋友,大家好。今天我们来聊聊Pandas的两个核心数据结构——Series和DataFrame。说实话,我刚接触Pandas那会儿,也觉得不就是个表格嘛,有啥好学的?直到我在处理一批MEMS加速度计的测试数据时,发现用纯Python列表操作,代码又臭又长,调试到半夜。后来用Pandas重写,半小时搞定。嗯,这就是工具的力量。

这一章,我会带着大家从创建、索引、切片,到筛选和排序,一步步把这两个数据结构吃透。你想想看,传感器芯片测试数据动辄几十万行,没有Pandas,你手动去数?不现实。

4.1 Series:一维带标签的数组

Series说白了就是一列数据,每个数据都有一个标签(索引)。我习惯把它想象成Excel里的一列,但比Excel灵活得多。

4.1.1 创建Series

创建Series最简单的方式,就是传一个列表进去。比如我们记录5个温度传感器的读数:

import pandas as pd

# 从列表创建
temp_data = [25.3, 26.1, 24.8, 27.0, 25.9]
s = pd.Series(temp_data)
print(s)

输出是这样的:

0    25.3
1    26.1
2    24.8
3    27.0
4    25.9
dtype: float64

注意看,左边自动生成了0到4的整数索引。但实际项目中,我们更希望用有意义的标签。比如用传感器编号:

s = pd.Series(temp_data, index=['S1', 'S2', 'S3', 'S4', 'S5'])
print(s)
S1    25.3
S2    26.1
S3    24.8
S4    27.0
S5    25.9
dtype: float64
我的小习惯:创建Series时,尽量指定有意义的index。我在项目中吃过亏,用默认整数索引,结果后面合并数据时,索引对不上,排查了半天。后来我强制自己,凡是传感器数据,一律用传感器ID或时间戳做索引。

还可以用字典创建,键自动变成索引:

data_dict = {'S1': 25.3, 'S2': 26.1, 'S3': 24.8}
s = pd.Series(data_dict)

4.1.2 索引与切片

Series的索引有两种方式:位置索引和标签索引。这里有个坑,我当年刚学时踩过。

位置索引:用数字,从0开始。

print(s[0])   # 第一个元素
print(s[1:3]) # 第2到第3个元素(左闭右开)

标签索引:用我们自定义的标签。

print(s['S1'])       # 标签为'S1'的元素
print(s[['S1','S3']]) # 多个标签
注意:如果索引是整数,比如0,1,2...,那么s[0]到底是位置索引还是标签索引?Pandas会优先按标签索引。我曾经在这里翻过车,后来我统一用.loc和.iloc来区分,避免歧义。

我建议你养成习惯:

  • .loc[] —— 基于标签索引
  • .iloc[] —— 基于位置索引
print(s.loc['S1'])   # 明确用标签
print(s.iloc[0])     # 明确用位置

4.2 DataFrame:二维表格数据结构

DataFrame才是我们真正干活的主力。它就像一张Excel表格,有行有列。每个传感器芯片的测试数据,通常就是一张DataFrame。

4.2.1 创建DataFrame

最常见的创建方式是从字典创建。比如我们记录一批压力传感器的测试结果:

data = {
    '传感器ID': ['P001', 'P002', 'P003', 'P004'],
    '量程(MPa)': [10, 20, 10, 50],
    '精度(%)': [0.5, 0.2, 0.5, 0.1],
    '输出(mV)': [100.2, 200.5, 99.8, 501.3],
    '合格': [True, True, False, True]
}
df = pd.DataFrame(data)
print(df)

输出:

  传感器ID  量程(MPa)  精度(%)  输出(mV)    合格
0    P001       10      0.5    100.2   True
1    P002       20      0.2    200.5   True
2    P003       10      0.5     99.8  False
3    P004       50      0.1    501.3   True

你看,自动生成了行索引0,1,2,3。列名就是字典的键。

也可以从CSV文件读取,这是实际项目中最常用的:

df = pd.read_csv('sensor_test_data.csv')
实战经验:我在处理一批温湿度传感器数据时,原始CSV文件有30万行,用Excel打开直接卡死。用Pandas的read_csv,几秒钟就读进来了。这就是为什么我们做芯片测试数据分析,必须用Pandas。

4.2.2 索引与切片

DataFrame的索引和切片比Series复杂一些,但掌握了规律就很简单。

列索引:

# 取单列,返回Series
print(df['传感器ID'])

# 取多列,返回DataFrame
print(df[['传感器ID', '输出(mV)']])

行索引(切片):

# 前两行
print(df[0:2])

# 用标签索引(如果行索引是自定义的)
print(df.loc[0:2])  # 注意:loc是闭区间
print(df.iloc[0:2]) # iloc是左闭右开

行列同时索引:

# 取第1行第2列
print(df.iloc[0, 1])

# 取传感器ID为P002的精度和输出
print(df.loc[df['传感器ID'] == 'P002', ['精度(%)', '输出(mV)']])
避坑指南:我曾经在写筛选条件时,忘了加括号,导致逻辑运算优先级出错。比如 df[(df['量程'] > 10) & (df['合格'] == True)],括号不能省。每个条件都要用括号括起来,这是血的教训。

4.3 数据筛选

数据筛选是测试数据分析中最常用的操作。说白了,就是从海量数据中找出我们关心的那部分。

4.3.1 布尔索引

这是最直观的筛选方式。比如找出所有不合格的传感器:

fail_df = df[df['合格'] == False]
print(fail_df)

输出:

  传感器ID  量程(MPa)  精度(%)  输出(mV)    合格
2    P003       10      0.5     99.8  False

多条件筛选:

# 量程大于10且精度小于0.5的传感器
result = df[(df['量程(MPa)'] > 10) & (df['精度(%)'] < 0.5)]
print(result)

4.3.2 使用isin()方法

当我们需要筛选多个特定值时,用isin()比多个or条件更简洁:

# 筛选传感器ID为P001和P003的数据
selected = df[df['传感器ID'].isin(['P001', 'P003'])]

4.3.3 使用query()方法

我个人很喜欢query(),因为它写起来更像SQL,可读性更好:

# 等价于上面的多条件筛选
result = df.query('量程(MPa) > 10 and 精度(%) < 0.5')
为什么推荐query? 在复杂筛选条件中,不用写一堆括号和&符号,代码更清爽。我在处理有20多个筛选条件的测试数据时,用query()让代码量减少了将近一半。

4.4 数据排序

排序也是家常便饭。比如按输出值从小到大排,或者按量程从大到小排。

4.4.1 按单列排序

# 按输出值升序
df_sorted = df.sort_values(by='输出(mV)')
print(df_sorted)

# 按输出值降序
df_sorted_desc = df.sort_values(by='输出(mV)', ascending=False)

4.4.2 按多列排序

先按量程升序,量程相同的再按精度降序:

df_sorted_multi = df.sort_values(by=['量程(MPa)', '精度(%)'], ascending=[True, False])

4.4.3 按索引排序

# 按行索引排序
df_sorted_index = df.sort_index()

# 按列名排序
df_sorted_columns = df.sort_index(axis=1)
我的经验:排序后记得重置索引,否则索引顺序会乱。用 df.reset_index(drop=True) 可以重置为连续的整数索引。drop=True表示丢弃原来的索引列。

4.5 知识体系结构图

下面这张图,是我自己总结的Pandas数据结构核心逻辑。你看一遍,心里就有谱了。

Pandas数据结构核心知识体系 Pandas数据结构 Series(一维) DataFrame(二维) 创建 索引与切片 创建 索引与切片 共同核心操作 数据筛选 数据排序 布尔索引 query()方法 核心:掌握创建 → 索引切片 → 筛选排序 这一条线,就能应对90%的测试数据分析场景

4.6 实战小案例:传感器测试数据快速分析

最后,我给大家一个完整的实战片段。假设我们有一批压力传感器的测试数据,需要找出量程在20MPa以上、精度优于0.3%的合格传感器,并按输出值降序排列。

import pandas as pd

# 模拟数据
data = {
    '传感器ID': ['P001', 'P002', 'P003', 'P004', 'P005'],
    '量程(MPa)': [10, 20, 30, 50, 10],
    '精度(%)': [0.5, 0.2, 0.3, 0.1, 0.8],
    '输出(mV)': [100.2, 200.5, 301.0, 501.3, 99.5],
    '合格': [True, True, True, True, False]
}
df = pd.DataFrame(data)

# 筛选:量程>=20,精度<=0.3,合格
result = df.query('量程(MPa) >= 20 and 精度(%) <= 0.3 and 合格 == True')

# 按输出值降序
result_sorted = result.sort_values(by='输出(mV)', ascending=False)

print(result_sorted)

输出:

  传感器ID  量程(MPa)  精度(%)  输出(mV)    合格
3    P004       50      0.1    501.3   True
2    P003       30      0.3    301.0   True
1    P002       20      0.2    200.5   True

你看,三行代码就搞定了。如果用手工在Excel里筛,得折腾好几分钟,还容易出错。

总结一下:Series和DataFrame是Pandas的基石。创建时注意索引设计,索引切片时用.loc和.iloc避免歧义,筛选排序时多用query()让代码更清晰。这些基本功打扎实了,后面处理复杂的传感器测试数据,你会觉得游刃有余。

好了,这一章就到这里。记住,多动手敲代码,光看是学不会的。下次见。


专注资料整理