在日常开发中,我们经常需要快速了解一个 CSV 数据文件的结构和内容——有多少行、每列是什么类型、数值列的分布情况如何。通常的做法是打开 Excel 或写一段临时脚本,但都不够快捷。
今天我们用 OpenCode 从零开始,仅用自然语言对话,4 分钟内写出一个命令行 CSV 分析工具 csvstat。它接受一个 CSV 文件路径,自动输出:
技术栈:Python 3,仅用标准库(csv、collections、statistics),零外部依赖。
sample.csv)打开终端,进入项目目录,对 OpenCode 说:
> 我对 OpenCode 说:
> 帮我写一个 Python 命令行工具 csvstat.py,接收 CSV 文件路径作为参数,读取文件后输出行数、列数、列名,以及每列的数据类型判断(数值型还是分类型)。
> OpenCode 的响应:
> OpenCode 自动生成了完整的 Python 脚本,包含 csv.DictReader 读取文件、detect_type() 函数判断列类型、以及 sys.argv 处理命令行参数。代码约 40 行,可以直接运行。
我运行 python csvstat.py sample.csv,立刻看到了行列统计和类型判断结果。此时核心框架已就位。
要点: 需求描述越具体越好——明确输入(文件路径)、输出(具体统计项)、边界(类型判断规则)。
> 我对 OpenCode 说:
> 对数值型列加上最小值、最大值、平均值、中位数和标准差的计算,用 statistics 模块。分类列显示唯一值个数和前 5 个最常见的值。
> OpenCode 的响应:
> OpenCode 识别到需要引入 statistics 模块和 collections.Counter,在 analyze() 函数中新增了分支逻辑——数值列调用 mean()、median()、stdev(),分类列用 Counter.most_common(5) 统计频率。修改精准,没有改动无关代码。
新增约 20 行,统计功能直接到位。用 statistics.stdev() 时 OpenCode 还自动加了 len(nums) > 1 的判空保护,避免了只有一条数据时的异常。
要点: 增量迭代是 OpenCode 的核心使用模式——先跑通骨架,再逐步加功能。每次只提一个明确需求,OpenCode 的修改会更精准。
> 我对 OpenCode 说:
> 加上异常处理:文件不存在时给出友好提示。另外支持自定义分隔符参数,比如制表符分隔的 TSV 文件也能处理。
> OpenCode 的响应:
> OpenCode 在文件读取外层加了 try-except,捕获 FileNotFoundError 输出 "文件不存在" 提示。分隔符方面,在命令行参数中增加了可选的第二个参数 delimiter,并对 \t 做了转义处理。同时将 encoding='utf-8' 改为 utf-8-sig,以兼容带 BOM 的 CSV 文件(这是 Excel 导出的常见格式)。
要点: 让 OpenCode 处理边界情况时,把场景说清楚("文件不存在"、"TSV 文件"、"Excel 导出的 CSV"),它会给出比你预期更周全的方案。
#!/usr/bin/env python3
"""csvstat - 命令行 CSV 数据分析工具"""
import csv
import sys
from collections import Counter
from statistics import mean, median, stdev
def detect_type(values):
"""检测列数据类型:numeric 或 categorical"""
score = 0
total = 0
for v in values:
if v.strip() == '':
continue
total += 1
try:
float(v)
score += 1
except ValueError:
pass
return 'numeric' if total > 0 and score / total >= 0.5 else 'categorical'
def read_csv(filepath, delimiter=','):
with open(filepath, 'r', encoding='utf-8-sig') as f:
reader = csv.DictReader(f, delimiter=delimiter)
headers = reader.fieldnames
rows = [row for row in reader]
return headers, rows
def analyze(headers, rows):
print(f"总行数: {len(rows)}")
print(f"总列数: {len(headers)}")
print(f"列名: {', '.join(headers)}\n")
for col in headers:
values = [row.get(col, '') for row in rows]
non_empty = [v for v in values if v.strip() != '']
col_type = detect_type(non_empty)
missing = len(values) - len(non_empty)
print(f"┌─ {col}")
print(f"├─ 类型: {col_type} | 缺失: {missing} | 有效: {len(non_empty)}")
if col_type == 'numeric':
nums = [float(v) for v in non_empty]
print(f"├─ 最小值: {min(nums):.2f}")
print(f"├─ 最大值: {max(nums):.2f}")
print(f"├─ 平均值: {mean(nums):.2f}")
print(f"├─ 中位数: {median(nums):.2f}")
if len(nums) > 1:
print(f"└─ 标准差: {stdev(nums):.2f}")
else:
print(f"└─ 标准差: N/A")
else:
counter = Counter(non_empty)
print(f"├─ 唯一值: {len(counter)}")
top = counter.most_common(5)
for i, (val, cnt) in enumerate(top):
prefix = '└─' if i == len(top) - 1 else '├─'
print(f"{prefix} [{cnt}次] {val}")
print()
def main():
if len(sys.argv) < 2:
print("用法: python csvstat.py <CSV文件路径> [分隔符]")
print("示例: python csvstat.py data.csv")
print("示例: python csvstat.py data.tsv '\\t'")
sys.exit(1)
filepath = sys.argv[1]
delimiter = sys.argv[2] if len(sys.argv) > 2 else ','
try:
if delimiter == '\\t':
delimiter = '\t'
headers, rows = read_csv(filepath, delimiter)
analyze(headers, rows)
except FileNotFoundError:
print(f"错误: 文件 '{filepath}' 不存在")
sys.exit(1)
except Exception as e:
print(f"错误: {e}")
sys.exit(1)
if __name__ == '__main__':
main()
用 OpenCode 开发这个 CSV 分析工具,全程没有手写一行代码,只靠自然语言描述需求,4 分钟内从零到完整可运行。实际只做了三件事:
描述整体需求 → OpenCode 生成主流程框架
补充统计细节 → OpenCode 精准插入新功能
加固边界情况 → OpenCode 给出了比预期更周全的处理
对比传统开发方式:手动查 csv.DictReader API、写统计逻辑、处理异常分支,保守估计需要 20-30 分钟。OpenCode 将效率提升了 5 倍以上,而且代码质量不输手写——命名清晰、逻辑分层、边界处理到位。
这个工具后续还可以用 OpenCode 继续扩展:加 --chart 输出 ASCII 柱状图、加 --filter 按条件过滤行、甚至导出为 Markdown 表格——真正实现了"想法即代码"。