🔥
个人主页:
杨利杰YJlio
❄️
个人专栏:
《Sysinternals实战教程》
《Windows PowerShell 实战》
《WINDOWS教程》
《IOS教程》
《微信助手》
《锤子助手》
《Python》
《Kali Linux》
《那些年未解决的Windows疑难杂症》
🌟
让复杂的事情更简单,让重复的工作自动化

《超简单:用 Python 让 Excel 飞起来》读书笔记:3.5.3 数据的选取和处理:选列、选行、筛选、排序、增删列
- 1. 3.5.3 数据的选取和处理:选列、选行、筛选、排序、增删列
- 2. 为什么这一节是 pandas 办公自动化的核心
- 3. 按列选取:data['c1'] 和 data[['c1']] 的区别
- 4. 按行选取:head、iloc、loc 怎么选
- 5. 按区块选取:iloc[row, col] 与 loc[rows, cols]
- 6. 条件筛选:从表里只保留符合条件的行
- 7. 排序:sort_values 和 sort_index
- 8. 新增列与删除行列:让表格真正完成加工
- 9. 把操作串起来:一个典型办公处理链
- 10. 常见问题和踩坑提醒
- 11. 总结提升

1. 3.5.3 数据的选取和处理:选列、选行、筛选、排序、增删列
V4修正版进度标记:本篇为 06月15日 第1篇,承接 06月07日第2篇“2.7.2 自定义函数”之后继续更新。
这一篇是我阅读《超简单:用 Python 让 Excel 飞起来》时整理的读书笔记,对应书籍中的 第3章 Python模块 / 3.5.3 数据的选取和处理。前面已经学习了如何把 Excel 或 CSV 读取成 DataFrame,也知道了如何把结果写回文件。到了这一节,才真正进入 pandas 办公自动化最常用的区域:从一张表里选出需要的数据,再进行筛选、排序、计算和删除。
真实办公场景里,我们很少只是“打开一张表看一眼”。更多时候是:只要某几列,只看前几行,筛出满足条件的数据,按金额或日期排序,新增一列计算结果,最后删除无关列并导出。这些动作在 Excel 里靠筛选、排序、公式和删除列完成,在 Python 里主要靠 DataFrame 的选取与处理完成。
本文重点围绕几个高频动作展开:按列选取、按行选取、按区块选取、条件筛选、排序、新增列、删除行列,以及如何把这些操作串成一个完整的数据处理链路。
我的理解是:DataFrame 的选取和处理,本质上就是把 Excel 里的“选列、筛选、排序、公式、删除”变成可以复用的代码流程。
为了演示方便,先准备一个小型 DataFrame。后面所有示例都基于这张表展开。
import pandas as pd
data = pd.DataFrame({
"c1": ["A", "B", "C", "D"],
"c2": [10, 30, 20, 30],
"c3": [100, 200, 150, 80],
}, index=["r1", "r2", "r3", "r4"])
print(data)
这张图展示的是 DataFrame 中“选列”和“选行”的基础思路。左侧是表格里的列和行,右侧对应的是 data['c1']、data[['c1']]、head()、iloc、loc 等常见写法。

从图中可以看出,DataFrame 的数据选取不是只有一种写法。按列、按行、按标签、按位置都可以,但每种写法背后的含义不同。真正写脚本时,不能只看代码短不短,而要看当前需求到底是“按字段名选”,还是“按行列位置选”。

2. 为什么这一节是 pandas 办公自动化的核心
在办公自动化里,读取文件只是第一步。真正决定效率的,是读取以后怎么处理数据。比如财务表里只保留“电子设备”,资产表里只保留某个部门,销售表里按金额降序排序,人员名单里新增一列处理状态。这些都属于数据选取和处理。
如果不用 pandas,这些操作可能要靠手动筛选、复制粘贴、排序和公式拖拽完成。问题是,只要数据量稍微大一点,或者每个月都要重复做,这种手工方式就会变成低效且容易出错的工作。
推荐把这一节当成“Excel 自动化处理链”的基本功:先会选,再会筛,再会排,再会算,最后会删和导出。
#mermaid-svg-fuiZFtgRdzHJkv7R{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fuiZFtgRdzHJkv7R .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fuiZFtgRdzHJkv7R .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fuiZFtgRdzHJkv7R .error-icon{fill:#552222;}#mermaid-svg-fuiZFtgRdzHJkv7R .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fuiZFtgRdzHJkv7R .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fuiZFtgRdzHJkv7R .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fuiZFtgRdzHJkv7R .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fuiZFtgRdzHJkv7R .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fuiZFtgRdzHJkv7R .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fuiZFtgRdzHJkv7R .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fuiZFtgRdzHJkv7R .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fuiZFtgRdzHJkv7R .marker.cross{stroke:#333333;}#mermaid-svg-fuiZFtgRdzHJkv7R svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fuiZFtgRdzHJkv7R p{margin:0;}#mermaid-svg-fuiZFtgRdzHJkv7R .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-fuiZFtgRdzHJkv7R .cluster-label text{fill:#333;}#mermaid-svg-fuiZFtgRdzHJkv7R .cluster-label span{color:#333;}#mermaid-svg-fuiZFtgRdzHJkv7R .cluster-label span p{background-color:transparent;}#mermaid-svg-fuiZFtgRdzHJkv7R .label text,#mermaid-svg-fuiZFtgRdzHJkv7R span{fill:#333;color:#333;}#mermaid-svg-fuiZFtgRdzHJkv7R .node rect,#mermaid-svg-fuiZFtgRdzHJkv7R .node circle,#mermaid-svg-fuiZFtgRdzHJkv7R .node ellipse,#mermaid-svg-fuiZFtgRdzHJkv7R .node polygon,#mermaid-svg-fuiZFtgRdzHJkv7R .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fuiZFtgRdzHJkv7R .rough-node .label text,#mermaid-svg-fuiZFtgRdzHJkv7R .node .label text,#mermaid-svg-fuiZFtgRdzHJkv7R .image-shape .label,#mermaid-svg-fuiZFtgRdzHJkv7R .icon-shape .label{text-anchor:middle;}#mermaid-svg-fuiZFtgRdzHJkv7R .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fuiZFtgRdzHJkv7R .rough-node .label,#mermaid-svg-fuiZFtgRdzHJkv7R .node .label,#mermaid-svg-fuiZFtgRdzHJkv7R .image-shape .label,#mermaid-svg-fuiZFtgRdzHJkv7R .icon-shape .label{text-align:center;}#mermaid-svg-fuiZFtgRdzHJkv7R .node.clickable{cursor:pointer;}#mermaid-svg-fuiZFtgRdzHJkv7R .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-fuiZFtgRdzHJkv7R .arrowheadPath{fill:#333333;}#mermaid-svg-fuiZFtgRdzHJkv7R .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fuiZFtgRdzHJkv7R .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fuiZFtgRdzHJkv7R .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fuiZFtgRdzHJkv7R .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fuiZFtgRdzHJkv7R .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fuiZFtgRdzHJkv7R .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-fuiZFtgRdzHJkv7R .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fuiZFtgRdzHJkv7R .cluster text{fill:#333;}#mermaid-svg-fuiZFtgRdzHJkv7R .cluster span{color:#333;}#mermaid-svg-fuiZFtgRdzHJkv7R div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fuiZFtgRdzHJkv7R .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fuiZFtgRdzHJkv7R rect.text{fill:none;stroke-width:0;}#mermaid-svg-fuiZFtgRdzHJkv7R .icon-shape,#mermaid-svg-fuiZFtgRdzHJkv7R .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fuiZFtgRdzHJkv7R .icon-shape p,#mermaid-svg-fuiZFtgRdzHJkv7R .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-fuiZFtgRdzHJkv7R .icon-shape .label rect,#mermaid-svg-fuiZFtgRdzHJkv7R .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fuiZFtgRdzHJkv7R .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fuiZFtgRdzHJkv7R .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fuiZFtgRdzHJkv7R :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
读取 DataFrame
选列 / 选行 / 选区块
条件筛选
排序
新增计算列
删除无关行列
导出 Excel / CSV
这个流程图可以理解为 pandas 处理办公表格的通用骨架。不同业务场景只是条件、列名和计算公式不同,底层动作基本都在这条链路里。
不要只记单个函数。真实工作里最有价值的不是会写 sort_values(),而是能把选取、筛选、排序、新增列、删除列串成稳定流程。

3. 按列选取:data[‘c1’] 和 data[[‘c1’]] 的区别
按列选取是最常见的操作。比如一张表里有几十列,但我只关心姓名、部门、金额、日期这些字段,就需要先把目标列选出来。
选取单列最常见的写法是:
col = data["c1"]
print(col)
print(type(col))
这时返回的是 Series,可以理解成一维数据。它像 Excel 里单独拿出来的一列,但不是完整二维表。
col_df = data[["c1"]]
print(col_df)
print(type(col_df))
这时返回的是 DataFrame,仍然保持二维表结构。虽然只选了一列,但它仍然有表头和表格形态。
这里的关键区别是:data[‘c1’] 返回 Series,data[[‘c1’]] 返回 DataFrame。
如果只是拿这一列做判断或计算,用 data["c1"] 很自然;如果后面还要拼接、导出、继续和其他列组成表,建议使用 data[["c1"]] 保留表结构。
推荐做法:新手阶段如果不确定后面是否还要保持表结构,优先用双中括号 data[[‘c1’]],这样更接近 Excel 表格思维。
选取多列也使用双中括号:
cols = data[["c1", "c3"]]
print(cols)
这种写法在实际工作中非常高频,比如只保留“资产编号、资产名称、使用部门、净值”这些关键字段。

4. 按行选取:head、iloc、loc 怎么选
按行选取常用于查看数据样例、截取前几行、按索引标签定位某条记录。读取一张陌生表后,我一般不会马上写复杂逻辑,而是先用 head() 看一下数据长什么样。
print(data.head())
print(data.head(3))
head() 默认查看前 5 行,head(3) 查看前 3 行。它适合做快速预览,尤其是刚读完 Excel 或 CSV 后,用来确认字段名、行数、数据格式是否符合预期。
如果要按“位置”选行,推荐使用 iloc。
print(data.iloc[0])
print(data.iloc[0:2])
iloc[0] 表示取第 0 行,也就是第一行;iloc[0:2] 表示取第 0 行到第 1 行,左闭右开。
如果要按“标签”选行,推荐使用 loc。
print(data.loc["r2"])
print(data.loc["r2":"r4"])
loc["r2"] 表示取索引标签为 r2 的行。需要注意的是,loc["r2":"r4"] 这种标签切片通常会包含右端,也就是包含 r4。
容易混淆的点:iloc 看位置,使用 0、1、2 这类数字;loc 看标签,使用索引名、日期、编号这类业务标签。
实际办公里,如果索引是自动生成的普通数字,iloc 更直观;如果索引是工号、日期、订单号,loc 读起来更像业务语言。

5. 按区块选取:iloc[row, col] 与 loc[rows, cols]
只选一列或一行还不够,实际处理表格时经常要选一块区域。比如取前 2 行前 2 列,或者取某几个行标签下的指定字段。这时就需要用到 iloc[row, col] 和 loc[rows, cols]。
iloc 按位置选区块:
print(data.iloc[0, 1])
print(data.iloc[0:2, 0:2])
data.iloc[0, 1] 表示第 0 行第 1 列,对应一个单元格值;data.iloc[0:2, 0:2] 表示前 2 行、前 2 列,对应一个小区块。
loc 按标签选区块:
print(data.loc["r2", "c3"])
print(data.loc["r1":"r3", ["c1", "c3"]])
data.loc["r2", "c3"] 表示取行标签为 r2、列名为 c3 的值;data.loc["r1":"r3", ["c1", "c3"]] 表示取 r1 到 r3 这些行,并只保留 c1 和 c3 两列。
这张图展示的是 iloc 和 loc 选区块的区别。左侧是按数字位置选择,右侧是按行标签和列名选择。

从图中可以看出,iloc 更像“第几行第几列”,loc 更像“哪个编号、哪个字段”。如果数据表有明确业务索引,比如员工编号、资产编号、日期,loc 的可读性会更好。
一句话记忆:iloc 用位置,loc 用标签。位置适合临时截取,标签适合业务定位。
注意:不要把 iloc 的位置数字和 loc 的标签混着用。很多选错数据的问题,本质就是这两个概念没分清。

6. 条件筛选:从表里只保留符合条件的行
筛选是 pandas 里最接近 Excel 筛选器的操作。它的本质不是修改原表,而是根据条件从原始表中“挑出符合条件的行”。
单条件筛选比较直观:
result = data[data["c2"] > 15]
print(result)
这段代码表示只保留 c2 大于 15 的行。它和 Excel 里筛选“c2 大于 15”是同一种思路。
复合条件需要使用 & 或 |。
result = data[(data["c2"] == 30) & (data["c3"] >= 100)]
print(result)
这表示同时满足两个条件:c2 等于 30,并且 c3 大于等于 100。
result = data[(data["c2"] == 10) | (data["c3"] < 100)]
print(result)
这表示满足任意一个条件即可:c2 等于 10,或者 c3 小于 100。
这张图展示的是条件筛选的过程。原始表经过条件判断后,只保留符合条件的行,其他行会被过滤掉。

从图中可以看出,条件筛选更像是一个漏斗。原始数据进入漏斗,只有满足条件的数据会留下来。这也是 pandas 做报表清洗时最常用的动作之一。
两个坑必须记住:复合条件要用 & 和 |,不能用 and 和 or;每个条件都要用括号包起来。
推荐做法:筛选后先打印 result.shape 或 len(result),确认保留下来的行数是否符合预期。
print("筛选后行数:", len(result))
print("筛选后形状:", result.shape)

7. 排序:sort_values 和 sort_index
排序也是办公表格里非常高频的动作。比如按金额从高到低、按日期从早到晚、按部门和金额组合排序。在 pandas 中,按列排序主要使用 sort_values(),按索引排序主要使用 sort_index()。
按某一列升序排序:
result = data.sort_values(by="c2")
print(result)
按某一列降序排序:
result = data.sort_values(by="c2", ascending=False)
print(result)
按多列排序也很常用。比如先按 c2 升序,再按 c3 降序:
result = data.sort_values(by=["c2", "c3"], ascending=[True, False])
print(result)
如果要按索引排序,可以使用:
result = data.sort_index()
print(result)
如果索引是日期、编号、工号,sort_index() 会非常有用。
这里可以把排序理解成:sort_values() 看数据列,sort_index() 看索引。
推荐做法:报表输出前最好明确排序规则,否则每次导出的表顺序可能不一致,后续对比和复核会很麻烦。

8. 新增列与删除行列:让表格真正完成加工
排序只是整理顺序,真正让数据产生新结果的动作,是新增列。它非常像 Excel 里新增一列公式。比如把 c2 乘以 2,生成一个新的 c4 列。
data["c4"] = data["c2"] * 2
print(data)
也可以写更接近业务逻辑的组合计算:
data["c4"] = data["c2"] * 10 + data["c3"]
print(data)
这类操作在真实报表里非常常见,比如新增“含税金额”“折扣后金额”“处理状态”“是否达标”等字段。
这张图展示的是排序与新增列的处理逻辑。左侧是通过 sort_values() 调整数据顺序,右侧是通过 data['c4'] = … 新增计算结果列。

从图中可以看出,排序解决的是“顺序问题”,新增列解决的是“结果生成问题”。在办公自动化里,这两个动作经常连在一起:先筛选和排序,再基于结果生成新字段。
删除列可以使用 drop(columns=…):
data2 = data.drop(columns=["c3"])
print(data2)
删除行可以使用 drop(index=…):
data2 = data.drop(index=["r1", "r3"])
print(data2)
如果使用 inplace=True,会直接修改原对象。
data.drop(columns=["c3"], inplace=True)
新手阶段不建议频繁使用 inplace=True。它会直接改掉原始对象,调试时不容易回退。更稳的做法是生成新变量,比如 data_new = data.drop(…)。
推荐做法:删除前先确认列名和行标签,删除后打印 data.columns 和 data.shape 做验证。
print(data.columns)
print(data.shape)

9. 把操作串起来:一个典型办公处理链
前面每个动作都是单点能力,但实际工作中更常见的是组合使用。比如现在有一个需求:筛选出 c2 >= 20 的行,然后按 c3 降序排序,再新增一列 c4 = c2 * 2,最后删除 c1。
这类需求在真实工作里非常像“从原始表生成处理后报表”。可以这样写:
result = data[data["c2"] >= 20] \\
.sort_values(by="c3", ascending=False)
result["c4"] = result["c2"] * 2
result = result.drop(columns=["c1"])
print(result)
这段代码把筛选、排序、新增列、删除列串在一起。读起来就是一条清晰的处理链:先留下需要的数据,再调整顺序,再生成结果字段,最后去掉无关字段。
这张图展示的是完整的数据处理流程:读取 DataFrame,然后依次完成选取、筛选、排序、新增列、删除,最后输出到 Excel 或 CSV。

从图中可以看出,一篇表格处理脚本的价值不在于某一个函数,而在于能不能把多个动作组织成稳定流程。对办公自动化来说,最终目标不是“会写一行代码”,而是把重复的数据处理动作固化下来。
这里的本质是:把 Excel 里的手工筛选、排序、公式、删除列,转换成一条可以重复执行的代码流水线。
建议保存这种处理链模板。以后遇到类似报表,只需要替换列名、条件和计算公式,就可以快速复用。

10. 常见问题和踩坑提醒
第一个常见问题是:为什么 data['c1'] 和 data[['c1']] 看起来差不多,但后面处理结果不一样?原因是前者返回 Series,后者返回 DataFrame。一个是一维数据,一个是二维表结构,后续拼接、导出、选择多列时行为会不同。
第二个常见问题是:为什么复合筛选条件报错?大概率是用了 and / or,或者条件没有加括号。pandas 里多个条件要用 & / |,并且每个条件都要括起来。
# 正确写法
result = data[(data["c2"] == 30) & (data["c3"] >= 100)]
第三个常见问题是:为什么 loc 和 iloc 选出来的数据不一样?因为 loc 走标签,iloc 走位置。标签不一定等于位置,尤其是索引被改成工号、日期、编号以后,更不能混用。
第四个常见问题是:为什么新增列时报 SettingWithCopyWarning?通常是因为你对筛选后的切片结果继续赋值,pandas 不确定你是在改原数据还是副本。更稳的做法是筛选后使用 .copy()。
result = data[data["c2"] >= 20].copy()
result["c4"] = result["c2"] * 2
这类警告不要无视。它不一定立刻导致错误,但说明你的赋值逻辑可能不够明确,后面脚本复杂后容易出现结果不稳定。
第五个常见问题是:为什么删除列以后找不到原字段了?如果你使用了 inplace=True,原对象已经被直接修改。新手阶段建议尽量生成新对象,保留原数据用于回退和对比。
推荐调试习惯:每一步处理后打印 shape、columns 或前几行结果,确认数据结构没有偏离预期。
print("当前形状:", result.shape)
print("当前列名:", result.columns.tolist())
print(result.head())

11. 总结提升
这一节的核心,是掌握 DataFrame 日常处理数据的几个基础动作:选列、选行、选区块、筛选、排序、新增列和删除。它们看起来是零散函数,但放到办公自动化里,其实就是一条完整的数据清洗与整理链路。
我把本文重点压缩成几句话:data['c1'] 返回 Series,data[['c1']] 返回 DataFrame;iloc 按位置选,loc 按标签选;复合筛选用 & / |,条件必须加括号;排序用 sort_values() 或 sort_index();新增列就是写一整列公式;删除时谨慎使用 inplace=True。
对我来说,这一节最有价值的地方,不是某个函数本身,而是开始把 Excel 的手工操作翻译成代码流程。只要这个思路建立起来,后续做月报、资产表、人员名单、设备清单、故障统计表,很多重复动作都可以自动化。
我的最终理解是:pandas 的表格处理能力,本质上是在用代码重建 Excel 的筛选、排序、公式和清洗流程。
后续写办公自动化脚本时,可以优先按“读取 → 选取 → 筛选 → 排序 → 新增列 → 删除 → 导出”的顺序设计脚本。
真正需要警惕的不是代码不会写,而是没验证每一步处理后的数据是否符合预期。表格处理最怕静默错误:代码不报错,但结果已经错了。
我最后把本节记成一句话:**会读表只是开始,会选、会筛、会排、会算、会删,才真正进入 Python 办公自动化。**
返回顶部

![[特殊字符]DeepSeek‑Harness(DSH)小白保姆教程-171主机测评](https://www.171host.com/wp-content/uploads/2026/08/20260816085112-6a817a009aabf-220x150.png)