Python文件与数据处理:面试官问“实验日志怎么解析”,别只会手动split
前面Python基础过了一遍,今天聊文件和数据处理的实操内容。
机器人开发中经常要和三类文件打交道:CSV格式的传感器日志、JSON格式的配置文件和通信数据、YAML格式的ROS2参数文件。这三种格式的读写是基本功,面试的时候经常被问到。
先说个真实场景。
老板跑过来跟你说:"昨天跑了一晚上的实验,数据都在那个CSV里,你帮我分析一下成功率。"你打开文件一看,几万行数据,每行是时间戳、物体ID、抓取姿态、成功/失败。手动看?不可能。用Excel打开?卡死了。
这时候Python就派上用场了。几十行代码,读取、分析、出图,一气呵成。
CSV:传感器日志的标准格式
CSV是最简单的表格数据格式。Python内置了csv模块:
import csv
# 读取
with open("grasp_log.csv", "r") as f:
reader = csv.DictReader(f)
for row in reader:
print(row["object_id"], row["success"])
# 写入
with open("results.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["object_id", "success", "time"])
writer.writerow(["cup", "True", "2026-07-09 14:30:00"])
DictReader比普通的reader好用——它自动把第一行当列名,每行数据返回一个dict,用列名访问,比用索引清晰得多。
实际项目中,CSV文件经常有编码问题。中文路径、中文注释在Windows上特别容易出问题。建议统一用UTF-8编码:
with open("data.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
如果数据量大(几百万行),csv模块会比较慢。这时候可以上pandas,后面会专门讲。
JSON:通信和配置的标准格式
JSON是机器人系统中最常见的数据交换格式。ROS2的很多接口、API的返回值、配置文件都用JSON。
Python处理JSON非常简单:
import json
# 读取
with open("config.json", "r") as f:
config = json.load(f)
# 写入
config["max_speed"] = 1.5
with open("config.json", "w") as f:
json.dump(config, f, indent=2)
# 字符串和对象之间转换
json_str = json.dumps(config, ensure_ascii=False)
obj = json.loads(json_str)
indent=2让输出格式化,方便阅读。ensure_ascii=False让中文正常显示而不是变成Unicode转义。
一个容易踩的坑:JSON的key必须是字符串。如果你的dict用了int或tuple做key,json.dump会报错。解决方法是在序列化之前把key转成字符串。
还有一个实用的技巧:处理嵌套JSON时,用json.loads配合递归提取需要的字段:
def extract_field(data, field, default=None):
"""从嵌套dict中安全地提取字段"""
keys = field.split(".")
for key in keys:
if isinstance(data, dict):
data = data.get(key, default)
else:
return default
return data
# 用法
speed = extract_field(response, "robot.status.max_speed", 0.0)
YAML:ROS2的配置语言
如果你用ROS2,YAML是绕不过去的。ROS2的参数文件、Launch文件中的参数配置,都是YAML格式。
Python处理YAML需要安装PyYAML库:pip install pyyaml。
import yaml
# 读取
with open("params.yaml", "r") as f:
params = yaml.safe_load(f)
# 写入
with open("output.yaml", "w") as f:
yaml.dump(params, f, default_flow_style=False)
注意一定要用yaml.safe_load而不是yaml.load。后者有安全风险——恶意的YAML文件可以执行任意Python代码。safe_load限制了可反序列化的类型,避免了这个问题。
一个典型的ROS2参数YAML文件长这样:
lidar_node:
ros__parameters:
scan_range: 30.0
scan_freq: 10
port: "/dev/ttyUSB0"
读取后就是一个嵌套dict:params["lidar_node"]["ros__parameters"]["scan_range"]。
路径处理:os.path vs pathlib
处理文件路径,Python有两个选择:传统的os.path和现代的pathlib。推荐用pathlib——它是面向对象的,用起来更直观:
from pathlib import Path
# 拼接路径
data_dir = Path("/home/user/robot_data")
log_file = data_dir / "logs" / "scan_001.csv"
# 检查文件是否存在
if log_file.exists():
print(f"File size: {log_file.stat().st_size} bytes")
# 遍历目录下所有CSV文件
for csv_file in data_dir.glob("**/*.csv"):
print(csv_file.name)
# 读取文件内容
lines = log_file.read_text().splitlines()
pathlib的/运算符用来拼接路径,glob支持递归搜索,read_text和write_text一行搞定文件读写。比os.path那一堆字符串操作优雅太多。
大文件处理的注意事项
当CSV文件超过百万行的时候,csv模块会变得很慢。这时候有两个选择:一是用pandas的read_csv,它底层是C实现,速度快很多;二是用生成器逐行读取,避免一次性把整个文件加载到内存。
# 生成器方式:内存友好
def read_large_csv(filepath):
with open(filepath, "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
yield row # 每次只返回一行
# 使用
for row in read_large_csv("million_rows.csv"):
process(row)
还有一个常见坑:写入CSV时忘记加newline=""参数,在Windows上会多出空行。加上newline=""让csv模块自己控制换行,就不会出这个问题。
补充一个实际工作中经常遇到的场景:解析机器人日志文件。很多硬件设备输出的日志格式不是标准的CSV或JSON,而是自定义的文本格式。这时候需要用正则表达式配合文件处理来提取数据。Python的re模块非常强大,建议花点时间熟悉常用的正则语法,在实际工作中这个技能特别实用。
给正在准备面试的你
文件处理在面试中不算高频考点,但在实际工作中是每天都要用的。建议你把CSV、JSON、YAML的读写都练一遍,特别是pathlib的使用。面试的时候如果聊到数据处理,能自然地提到这些工具,说明你有实际项目经验。
下篇进入NumPy的世界——机器人数据处理的Python标配。NumPy是Python科学计算的基石,做矩阵运算、处理传感器数据、跑深度学习模型,都离不开它。
如果这篇文章对你有帮助,欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。
「机器人软件开发面试·从入门到精通」连载系列 上一篇:第69篇 Python面向对象——和C++的对比理解 下一篇预告:第71篇 NumPy入门——机器人数据处理的Python标配
有任何问题欢迎评论区留言,我会尽量回复。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)