2. Pandas入门:DataFrame与Series结构,从CSV/TXT加载仿真数据
做仿真数据处理,说白了就是跟表格打交道。MATLAB里我们用table,Python里就是Pandas。我个人习惯把Pandas叫做“Python界的Excel”,但比Excel快得多,也灵活得多。
这一章,咱们就搞定两个核心数据结构:Series和DataFrame。然后直接从CSV和TXT文件里把仿真数据拽进来。
2.1 两个核心结构:Series和DataFrame
先别急着敲代码,咱们把概念理清楚。
| 结构 | 类比 | 特点 |
|---|---|---|
| Series | Excel里的一列 | 带标签的一维数组,每个元素有索引 |
| DataFrame | Excel里的整个表格 | 二维结构,多列Series组成,有行索引和列名 |
你想想看,仿真数据里最常见的场景是什么?时间序列、电压值、电流值。每一列就是一个Series,所有列拼在一起就是DataFrame。
核心记忆点:DataFrame = 多个Series的集合,共享同一个行索引。
2.2 创建Series和DataFrame
咱们直接上手。先创建一个Series:
import pandas as pd
# 从列表创建Series
voltage = pd.Series([3.3, 3.31, 3.29, 3.32, 3.30])
print(voltage)
输出长这样:
0 3.30
1 3.31
2 3.29
3 3.32
4 3.30
dtype: float64
左边是索引,右边是值。默认索引从0开始,但你可以自己指定:
time = pd.Series([0.0, 0.1, 0.2, 0.3, 0.4], index=['t0', 't1', 't2', 't3', 't4'])
print(time)
DataFrame的创建更常用。我一般用字典来创建:
data = {
'time_ms': [0.0, 0.1, 0.2, 0.3, 0.4],
'voltage_V': [3.30, 3.31, 3.29, 3.32, 3.30],
'current_A': [0.12, 0.13, 0.11, 0.14, 0.12]
}
df = pd.DataFrame(data)
print(df)
输出:
time_ms voltage_V current_A
0 0.0 3.30 0.12
1 0.1 3.31 0.13
2 0.2 3.29 0.11
3 0.3 3.32 0.14
4 0.4 3.30 0.12
嗯,这里要注意:字典的键变成了列名,值变成了列数据。整齐得很。
2.3 从CSV加载仿真数据
这才是咱们的重头戏。仿真软件导出的数据,十有八九是CSV格式。我遇到过很多次,同事导出来的CSV文件编码不对、分隔符不是逗号、表头有多余行……各种坑。
标准加载方式:
df = pd.read_csv('simulation_results.csv')
print(df.head()) # 只看前5行
但现实往往不这么美好。咱们看看常用参数:
| 参数 | 作用 | 常用值 |
|---|---|---|
sep |
指定分隔符 | ','(默认)、'\t'、';' |
header |
指定表头行 | 0(第一行)、None(无表头) |
skiprows |
跳过前N行 | 2、[0,2,3] |
encoding |
文件编码 | 'utf-8'、'gbk'、'latin1' |
na_values |
指定缺失值标记 | ['NA', 'null', '-999'] |
我曾经踩过的坑:有一次从某国产仿真软件导出CSV,默认编码是gbk,直接用read_csv报错。后来加了encoding='gbk'才搞定。如果你遇到UnicodeDecodeError,先试试encoding='latin1',基本能通吃。
实战案例——加载一个带注释的仿真数据文件:
df = pd.read_csv(
'motor_sim.csv',
skiprows=2, # 跳过前两行注释
sep=',', # 逗号分隔
encoding='utf-8',
na_values=['NaN', 'inf', '-inf']
)
2.4 从TXT加载仿真数据
TXT文件其实跟CSV差不多,只是分隔符更自由。常见的有空格分隔、制表符分隔、固定宽度。
空格分隔的TXT:
df = pd.read_csv('data.txt', sep='\s+', header=None)
sep='\s+'表示一个或多个空白字符,非常实用。
制表符分隔:
df = pd.read_csv('data.tsv', sep='\t')
固定宽度文件:
df = pd.read_fwf('fixed_width.txt', widths=[8, 12, 10])
小技巧:不确定文件格式时,先用文本编辑器打开看一眼。我习惯用head -20 data.txt(Linux/Mac)或直接在VS Code里预览前20行。看清楚分隔符和表头再写代码,省得反复试错。
2.5 知识结构图
下面这张图把本章的核心逻辑串起来了:
2.6 数据加载后的快速检查
数据加载进来,别急着分析。先做三件事:
- 看形状:
df.shape——返回(行数, 列数) - 看信息:
df.info()——列名、非空数量、数据类型 - 看头尾:
df.head()和df.tail()——确认数据是否正确
我每次加载完数据,第一件事就是跑df.info()。它能快速暴露问题:比如某列本该是数值型,结果显示object,说明里面有非数字字符。
# 快速检查套路
print("数据形状:", df.shape)
print("\n列名:", df.columns.tolist())
print("\n数据类型:")
print(df.dtypes)
print("\n前3行:")
print(df.head(3))
避坑指南:如果某列是时间数据,记得用pd.to_datetime()转换。我曾经因为没转换时间列,后面做时序分析时全乱套了。
2.7 实战:加载一个真实的仿真数据
假设你有一个仿真结果文件step_response.csv,内容如下:
# Step Response Data
# Time(ms), Voltage(V), Current(mA)
0.0, 0.0, 0.0
0.1, 1.2, 5.3
0.2, 2.8, 8.7
0.3, 3.9, 10.2
0.4, 4.5, 10.8
0.5, 4.8, 11.0
加载代码:
df = pd.read_csv(
'step_response.csv',
skiprows=2, # 跳过注释行
names=['time_ms', 'voltage_V', 'current_mA'] # 自定义列名
)
print(df)
输出:
time_ms voltage_V current_mA
0 0.0 0.0 0.0
1 0.1 1.2 5.3
2 0.2 2.8 8.7
3 0.3 3.9 10.2
4 0.4 4.5 10.8
5 0.5 4.8 11.0
干净利落。接下来你就可以用这些数据做分析、画图、甚至直接传给MATLAB联调。
嗯,这一章的内容就到这里。Pandas的DataFrame和Series是后续所有操作的基础,CSV/TXT加载是数据入门的第一个关卡。把这两个东西练熟,后面的路就好走了。