→ 像一列 Excel 数据,有索引(行名)+ 值
→ 适用于单变量:价格、年龄、温度…
DataFrame
→ 二维表格(多列 Series)
→ 像一张 Excel 表,列是字段,行是记录
→ 几乎所有数据处理都围绕它展开
选 → .loc[]
, .iloc[]
, []
→ "我要哪几行/列?" — 按标签、位置、条件筛选
算 → .apply()
, + - * /
, groupby().agg()
→ "每行/每组怎么算?" — 元素级、行/列级、分组聚合
合 → merge()
, concat()
, join()
→ "表和表怎么拼?" — 横向拼(列扩展)、纵向拼(行追加)、键关联
整 → drop()
, rename()
, astype()
, fillna()
→ "数据不干净怎么办?" — 删改列、改类型、填缺失、去重…
"对列操作,按行计算"
— 大部分函数默认axis=0
(按行方向聚合)
— 想对行操作?加axis=1
— 想分组?先groupby(列名)
,再.sum()
/.mean()
/.apply()
"把数据看成表,操作就是:选列 → 分组 → 计算 → 合并"
你不需要记函数名,只要问自己:
df[['A','B']]
或 df.loc[...]
df.groupby('category')
.mean()
, .apply(my_func)
.merge(other_df, on='key')
✅ 掌握这个思维框架,你就能"推理"出90%的 Pandas 用法,不用死记!
ndarray
(N维数组) — 所有操作都围绕它
→ 像数学中的"张量":1D向量、2D矩阵、3D立方体…
→ 所有元素同类型、连续内存 → 快!
np.array([...])
— 从列表创建np.zeros()
, np.ones()
, np.arange()
, np.linspace()
— 快速造数据np.random.rand(...)
— 随机数→ 问自己:"我要什么形状?什么初始值?"
arr[i]
, arr[i, j]
— 像列表,但支持多维arr[start:stop:step]
— 切片(不复制!是视图)arr[条件]
— 布尔索引(超实用!)arr[[行索引], [列索引]]
— 花式索引(复制)→ 问自己:"我要哪部分数据?按位置?按条件?"
+ - * / **
— 元素级运算(自动广播!)np.sum()
, np.mean()
, np.max()
— 聚合(注意 axis=
)@
或 np.dot()
— 矩阵乘法np.where(条件, A, B)
— 条件赋值→ 问自己:
np.func(..., axis=0/1)
@
np.where
"广播(Broadcasting) + 向量化(Vectorization) = 高效"
"把数据看成数学对象 — 向量 / 矩阵,用广播和轴操作代替循环"
你不需要记函数,只要问自己:
.shape
看维度axis=0
(行方向)或 axis=1
(列方向)+ - * /
arr[arr > 0]
"画布(Figure)→ 坐标系(Axes)→ 画线/点/柱(plot/bar/scatter…)"
所有图都由这三层构成:
Figure
:整个窗口/画布(可含多个子图)Axes
:一个坐标系(带刻度、标签、图例)→ 你实际画图的地方plot()
等:在 Axes 上绘制具体图形根据数据关系选图形类型:
数据关系 | 推荐图形 | 函数 |
---|---|---|
趋势(x→y) | 折线图 | .plot(x, y) |
分布(单变量) | 直方图 | .hist(data) |
关系(x↔y) | 散点图 | .scatter(x, y) |
比较(分类 vs 值) | 柱状图 | .bar(labels, vals) |
占比 | 饼图 | .pie(vals) |
→ 问自己:"我想表达什么关系?"
所有样式都通过"关键词参数"控制:
plt.plot(x, y, color='red', linewidth=2, linestyle='--', marker='o')
常用关键词:
color
/ c
→ 颜色linewidth
/ lw
→ 线宽linestyle
/ ls
→ 线型('-'
, '--'
, ':'
)marker
→ 点形状('o'
, 's'
, '^'
)label
→ 图例标签alpha
→ 透明度→ 问自己:"线/点/柱要长什么样?"
画完主体,加"装饰层":
plt.title("标题")
plt.xlabel("X轴标签")
plt.ylabel("Y轴标签")
plt.legend() # 显示图例(需plot时设label)
plt.grid(True) # 加网格
plt.xlim(xmin, xmax) # 调轴范围
→ 问自己:"读者需要什么辅助信息?"
import matplotlib.pyplot as plt
plt.plot(x, y)
plt.show()
→ 适合简单单图,自动创建 Figure + Axes
fig, ax = plt.subplots()
ax.plot(x, y, label='line')
ax.set_title("My Plot")
ax.legend()
plt.show()
→ 适合多子图、精细控制 —— 推荐掌握这个!
非常好!在掌握"画什么图、怎么画"之后,"画完怎么输出" 是最后关键一步 —— 无论你是要保存、展示、嵌入报告还是发给别人。
以下是 Matplotlib 极简输出方式指南,帮你建立完整闭环思维:
plt.show()
plt.plot(x, y)
plt.show() # ← 弹出窗口 or 在 notebook 里直接显示
✅ 适用场景:
⚠️ 注意:
plt.show(block=False)
)plt.savefig()
plt.plot(x, y)
plt.savefig('my_plot.png', dpi=300, bbox_inches='tight')
✅ 常用参数:
dpi=300
→ 高清图(论文/出版用)bbox_inches='tight'
→ 自动裁剪空白边缘.png
, .jpg
, .pdf
, .svg
✅ 适用场景:
.pdf
, .svg
)→ 无限放大不模糊⚠️ 注意:
plt.show()
之前调用! 否则可能保存空白图fig, ax = plt.subplots()
ax.plot(x, y)
fig.savefig('plot.pdf', dpi=300, bbox_inches='tight')
import io
buf = io.BytesIO()
plt.savefig(buf, format='png')
buf.seek(0) # 重置指针
image_bytes = buf.getvalue() # ← 可直接返回给前端或 API
Figure
对象(供其他库或 GUI 嵌入)fig, ax = plt.subplots()
ax.plot(x, y)
return fig # ← 可传给 Streamlit, Panel, Tkinter 等
✅ 适用场景:
"画完图 → 要看用
show()
→ 要存用savefig()
→ 要传用BytesIO
或返回fig
"
加这一句开头:
import matplotlib
matplotlib.use('Agg') # ← 使用非GUI后端
import matplotlib.pyplot as plt
→ 避免 TclError: no display name...
错误
✅ 现在你拥有了完整闭环: 选图 → 画图 → 装饰 → 输出 —— 无论目标是屏幕、文件还是程序,都能推理应对!
需要"把图嵌入 PDF 报告"或"在网页显示"的具体例子?随时问我! 🖼️📤
"先选图型 → 再画数据 → 最后装饰,一切样式靠关键词参数"
你不需要记函数,只要问自己:
.plot()
/ .scatter()
/ .bar()
…color=
, marker=
, linestyle=
….set_title()
, .legend()
, .grid()
fig, axes = plt.subplots(2, 2)
🎯 目标:不背代码,靠思维选工具、避坑、高效处理
✅ 覆盖:CSV / Excel / JSON / Parquet / TXT + 常见坑 + 解决方案 + Excel 表头错位专项
格式 | 推荐读取 | 推荐输出 | 适用场景 |
---|---|---|---|
CSV | pd.read_csv() | df.to_csv() | 通用表格、轻量交换 |
Excel | pd.read_excel() | df.to_excel() | 业务报表、多Sheet、给人看 |
JSON | pd.read_json() | df.to_json() | API、嵌套结构、Web 数据 |
Parquet | pd.read_parquet() | df.to_parquet() | 大数据、高性能、列式存储 |
Pickle | pd.read_pickle() | df.to_pickle() | 临时缓存、Python 对象 |
TXT | open() / np.loadtxt | open().write() | 日志、矩阵、简单文本 |
✅ 默认推荐:CSV + Pandas —— 通用、可读、跨平台
🚀 性能推荐:Parquet —— 快、小、类型安全
# 读
df = pd.read_csv('data.csv', encoding='utf-8', na_values=['', 'NULL'])
# 写
df.to_csv('out.csv', index=False, encoding='utf-8-sig') # 避免多余行号 + Excel 友好
✅ 必设 index=False
(否则下次读多一列)
✅ 用 encoding
防中文乱码
✅ 用 na_values
统一缺失值
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')
→ 安装支持:pip install openpyxl
→ 用 header=N
指定真实列名所在行(从0开始计数)
df = pd.read_excel('data.xlsx', header=2) # 第3行是列名
skiprows
df = pd.read_excel('data.xlsx', skiprows=3, header=0) # 跳过前3行,第4行当列名
df_raw = pd.read_excel('data.xlsx', header=None)
# 假设列名分布在第2行和第3行
cols = df_raw.iloc[1].fillna('') + '_' + df_raw.iloc[2].fillna('')
cols = cols.str.strip('_')
df = df_raw.iloc[3:].reset_index(drop=True) # 从第4行开始是数据
df.columns = cols
def find_header_row(filepath, keyword='日期|产品|客户|金额'):
preview = pd.read_excel(filepath, header=None, nrows=20)
mask = preview[0].str.contains(keyword, na=False, regex=True)
return mask.idxmax() if mask.any() else 0
header_row = find_header_row('data.xlsx')
df = pd.read_excel('data.xlsx', header=header_row)
df = pd.read_json('data.json', orient='records') # 每行一个对象
✅ 关键参数 orient
:
'records'
→ [{"a":1}, {"a":2}]
'columns'
→ {"a": [1,2], "b": [3,4]}
→ 不确定结构?先 print(open('file.json').read()[:200])
预览!
df.to_parquet('data.parquet', engine='pyarrow')
df = pd.read_parquet('data.parquet')
✅ 安装:pip install pyarrow
✅ 优点:快、小、类型保留、支持分区
问题 | 原因 | 解决方案 |
---|---|---|
中文乱码 | 编码不匹配 | encoding='utf-8' / 'gbk' / 'utf-8-sig' |
大文件内存爆炸 | 一次性加载 | chunksize=10000 分块读/写 |
数字/日期变字符串 | 自动推断失败 | dtype={} , parse_dates=[] 明确指定 |
缺失值不统一 | NULL/N/A/-/空混用 | na_values=['NULL','N/A','-',''] 统一识别 |
Excel 列名错位 | 报表有标题/空行/合并单元格 | header=N , skiprows=M , 手动组合列名 |
Excel 读取慢 | 读了无用行列 | usecols="A:D" , nrows=1000 限定范围 |
"CSV通用,Parquet高效,Excel给人看,JSON给机器用 —— 读写必设编码,大文件用分块,脏数据提前洗,Excel表头用
header=
定位。"
场景 | 推荐格式 + 工具 |
---|---|
日常分析 / 数据交换 | ✅ CSV + Pandas |
大数据 / 性能优先 | ✅ Parquet + PyArrow |
业务汇报 / 非技术人员 | ✅ Excel + openpyxl + header=N |
Web API / 嵌套结构 | ✅ JSON + orient='records' |
临时缓存 / 中间结果 | ✅ Pickle(Python专用)或 Parquet(通用) |
def safe_read_excel(file_path, header_keyword='日期|产品|客户'):
# 自动检测列名行
preview = pd.read_excel(file_path, header=None, nrows=20)
mask = preview.iloc[:, 0].str.contains(header_keyword, na=False, regex=True)
header_row = mask.idxmax() if mask.any() else 0
# 读取完整数据
df = pd.read_excel(file_path, header=header_row)
# 清理:删除全空列、全空行
df = df.loc[:, df.columns.notna()]
df = df.dropna(how='all').reset_index(drop=True)
return df
✅ 这份文档现在完整覆盖:
你不需要背任何函数 —— 遇到任务,按"格式→场景→参数→避坑"四步推理,即可快速写出正确代码!
需要为你的具体文件定制读取逻辑?随时发结构/截图,我帮你写! 🚀📊