RSS
菜单
全部文章快讯开发科技深度热点

第 50 章 Excel 公式与 pandas 对照

内容摘要

上一篇讲了 Excel"功能按钮"与 pandas 的对照,本篇讲"公式"的对照——把 SUMIF、SUMIFS、COUNTIF、COUNTIFS、IF、IFS、INDEX/MATCH、LEFT/RIGHT/MID、IFERROR、RANK、ROUND、CONCATENATE 这些天天写的 Excel 公式,逐一翻译成 pandas 表达式。每节先给 Excel 公式写法,再给 pandas 等价代码(已实跑),最后列注意事项。前置知识:[第 49 章 Excel 常用功能与 pandas 对照](49-Excel常用功能与pandas对照.md)、[第 13 章 分组聚合:groupby](13-分组聚合:groupby.md)、[第 48 章 NumPy 与 pandas 协同](48-NumPy与pandas协同.md)。学完后你拿到一张带公式的 Excel 报表,能立刻用 pandas 复现全部计算逻辑。

📖 本篇简介:上一篇讲了 Excel"功能按钮"与 pandas 的对照,本篇讲"公式"的对照——把 SUMIF、SUMIFS、COUNTIF、COUNTIFS、IF、IFS、INDEX/MATCH、LEFT/RIGHT/MID、IFERROR、RANK、ROUND、CONCATENATE 这些天天写的 Excel 公式,逐一翻译成 pandas 表达式。每节先给 Excel 公式写法,再给 pandas 等价代码(已实跑),最后列注意事项。前置知识:第 49 章 Excel 常用功能与 pandas 对照、第 13 章 分组聚合:groupby、第 48 章 NumPy 与 pandas 协同。学完后你拿到一张带公式的 Excel 报表,能立刻用 pandas 复现全部计算逻辑。
Excel 公式是"单元格里写一段代码,逐格求值";pandas 是"整列向量化,一次算完"。理解这个差异,是理解所有公式对照的钥匙。

目录

1. 开篇:Excel 公式 ↔ pandas 总对照表

2. SUMIF / SUMIFS ↔ where + sum / groupby + sum

3. COUNTIF / COUNTIFS ↔ 布尔计数 / value_counts

4. IF / IFS ↔ np.where / np.select

5. SUM 整列 ↔ Series.sum

6. INDEX / MATCH ↔ loc

7. LEFT / RIGHT / MID ↔ str.slice

8. IFERROR ↔ fillna / where / 掩码

9. RANK ↔ rank

10. ROUND ↔ round

11. CONCATENATE / TEXT ↔ str 拼接与格式化

12. VLOOKUP 模糊匹配 ↔ merge_asof / pd.cut

13. 综合案例:按部门汇总超预算金额

14. 常见坑

15. 本章小结与练习题


1. 开篇:Excel 公式 ↔ pandas 总对照表

刚从 Excel 转 pandas 的人,最常问的一句话是:"我在 Excel 里写了 5 层嵌套的 IF,pandas 里怎么写?"这张总表先把地图给你:

| Excel 公式 | pandas 等价写法 | 说明 |

|------------|-----------------|------|

| =SUMIF(A:A, "销售", B:B) | df.loc[df.dept=="销售", "amount"].sum() | 条件求和 |

| =SUMIFS(C:C, A:A, "销售", B:B, "差旅") | df.loc[(df.dept=="销售")&(df.item=="差旅"), "amount"].sum() | 多条件求和 |

| =COUNTIF(C:C, ">60") | (df.score>=60).sum() | 条件计数 |

| =IF(A2>=60, "及格", "不及格") | np.where(df.score>=60, "及格", "不及格") | 二分支 |

| =IFS(A2>=90,"优",A2>=60,"良",TRUE,"差") | np.select([c1,c2,c3], ["优","良","差"]) | 多分支 |

| =SUM(B:B) | df["col"].sum() | 整列求和 |

| =INDEX(B:B, MATCH("A002", A:A, 0)) | df.set_index("code").loc["A002", "price"] | 双向查找 |

| =LEFT(A2, 3) / =RIGHT(A2, 3) / =MID(A2, 2, 3) | s.str[:3] / s.str[-3:] / s.str[1:4] | 字符串切片 |

| =IFERROR(A2/B2, 0) | (a/b).where(b!=0, other=np.nan).fillna(0) | 错误兜底 |

| =RANK(B2, B:B, 0) | s.rank(ascending=False, method="average") | 排名 |

| =ROUND(A2, 2) | s.round(2) | 四舍五入 |

| =A2&"-"&B2 / =TEXT(A2,"¥#,##0.00") | s1.str.cat(s2, sep="-") / s.map(lambda x: f"¥{x:,.2f}") | 拼接 / 格式化 |

| =VLOOKUP(A2, 区间, 2, TRUE) 模糊匹配 | pd.cut(...) 或 pd.merge_asof(...) | 分段 / 有序关联 |

💡 核心差异:Excel 公式写在单个单元格里,向下拖拽时行号自动变化;pandas 写在整列上,一次算完全表。所以 pandas 代码更短,但心智模型要从"格子"切换到"列"。

2. SUMIF / SUMIFS ↔ where + sum / groupby + sum

Excel 里 SUMIF 是"单条件求和",SUMIFS 是"多条件求和"。pandas 里等价写法有两种:布尔索引 + sum(一次性)和 groupby + sum(按组汇总)。

| Excel 公式写法 | pandas 等价代码 | 说明 |

|----------------|-----------------|------|

| =SUMIF(A:A, "销售", C:C) | df.loc[df.dept=="销售", "amount"].sum() | 单条件 |

| =SUMIFS(C:C, A:A, "销售", B:B, "差旅") | df.loc[(df.dept=="销售")&(df.item=="差旅"), "amount"].sum() | 多条件 |

| 按部门汇总 | df.groupby("dept")["amount"].sum() | 一次出所有组 |

import numpy as np
import pandas as pd

exp = pd.DataFrame({
    "dept": ["销售", "销售", "技术", "技术", "销售", "技术"],
    "item": ["差旅", "招待", "差旅", "设备", "办公", "差旅"],
    "amount": [1200, 800, 3000, 5000, 200, 1500],
})

# SUMIF: 销售部门的支出总和
total_sales = exp.loc[exp["dept"] == "销售", "amount"].sum()
print("SUMIF(销售) =", total_sales)

# SUMIFS: 销售部门 + 差旅 类
total_sales_travel = exp.loc[(exp["dept"] == "销售") & (exp["item"] == "差旅"), "amount"].sum()
print("SUMIFS(销售+差旅) =", total_sales_travel)

# 等价 groupby:一次得到所有部门×类别的汇总
g = exp.groupby(["dept", "item"])["amount"].sum()
print("groupby 透视:\n", g)
SUMIF(销售) = 2200
SUMIFS(销售+差旅) = 1200
groupby 透视:
 dept  item
技术    差旅      4500
      设备      5000
销售    办公       200
      差旅      1200
      招待       800
Name: amount, dtype: int64

注意事项:

  • 多条件之间用 &,每个条件必须加圆括号。
  • 如果你要的是"每个部门各自的 SUMIF",用 groupby 比写 N 次布尔索引快得多,也更不容易错。

3. COUNTIF / COUNTIFS ↔ 布尔计数 / value_counts

COUNTIF 是"数满足条件的行数"。pandas 里布尔 Series 求和就是计数(True=1,False=0)。

| Excel 公式写法 | pandas 等价代码 | 说明 |

|----------------|-----------------|------|

| =COUNTIF(C:C, ">60") | (df.score>=60).sum() | 条件计数 |

| =COUNTIFS(A:A, "销售", C:C, ">=60") | ((df.dept=="销售")&(df.score>=60)).sum() | 多条件 |

| =COUNTIF(A:A, "销售") | (df.dept=="销售").sum() 或 df.dept.value_counts()["销售"] | 频数 |

scores = pd.DataFrame({
    "name": ["张三", "李四", "王五", "赵六", "钱七"],
    "dept": ["销售", "技术", "销售", "技术", "销售"],
    "score": [90, 55, 72, 40, 88],
})

# COUNTIF: 成绩 >= 60 的人数
pass_cnt = (scores["score"] >= 60).sum()
print("及格人数 =", pass_cnt)

# COUNTIFS: 销售部门 且 及格
cnt = ((scores["dept"] == "销售") & (scores["score"] >= 60)).sum()
print("销售部门及格人数 =", cnt)

# value_counts:一次性数出每个部门出现次数
print("按部门计数:\n", scores["dept"].value_counts())
及格人数 = 3
销售部门及格人数 = 3
按部门计数:
 dept
销售    3
技术    2
Name: count, dtype: int64
⚠️ 常见坑:(df.x>0).sum() 得到的是 int,不是 DataFrame;不要写成 df[(df.x>0)].count(),那会返回每列的非空行数,不是你想要的。

4. IF / IFS ↔ np.where / np.select

Excel 的 IF 是二分支,IFS 是多分支(Excel 2019+ 才有)。pandas 对应 np.where(二分支)和 np.select(多分支)。

| Excel 公式写法 | pandas 等价代码 | 说明 |

|----------------|-----------------|------|

| =IF(A2>=60, "及格", "不及格") | np.where(s>=60, "及格", "不及格") | 二分支 |

| =IFS(A2>=90,"优",A2>=60,"良",TRUE,"差") | np.select([s>=90,s>=60], ["优","良"], default="差") | 多分支,从上往下匹配 |

s = pd.Series([95, 55, 72, 30, 88])

# IF: >=60 及格 否则 不及格
label = np.where(s >= 60, "及格", "不及格")
print("IF:\n", label)

# IFS: 多分支 np.select
conds = [s >= 90, s >= 60, s >= 0]
choices = ["优", "良", "差"]
grade = np.select(conds, choices, default="缺考")
print("IFS:\n", grade)
IF:
 ['及格' '不及格' '及格' '不及格' '及格']
IFS:
 ['优' '差' '良' '差' '良']

注意事项:

  • np.select 的条件列表从上往下匹配,命中第一个就停——这和 Excel IFS 完全一致。
  • 不要用 df.apply(lambda row: ...) 写条件分支,np.where / np.select 是向量化的,快几十倍(见第 48 章)。

5. SUM 整列 ↔ Series.sum

最简单的一个:=SUM(B:B) 就是 df["col"].sum()。

| Excel 公式写法 | pandas 等价代码 | 说明 |

|----------------|-----------------|------|

| =SUM(B:B) | df["col"].sum() | 整列求和 |

| =AVERAGE(B:B) | df["col"].mean() | 平均 |

| =MAX(B:B) / =MIN(B:B) | df["col"].max() / df["col"].min() | 最大最小 |

print("总和 =", s.sum())
print("平均 =", s.mean())
总和 = 340
平均 = 68.0
💡 pandas 默认会跳过 NaN 再聚合(skipna=True),Excel 的 SUM 也会自动忽略空单元格,行为一致。

6. INDEX / MATCH ↔ loc

Excel 里 INDEX + MATCH 是比 VLOOKUP 更灵活的"双向查找":MATCH 找到行号,INDEX 取值。pandas 里就是 loc——按索引标签或布尔掩码取数。

| Excel 公式写法 | pandas 等价代码 | 说明 |

|----------------|-----------------|------|

| =INDEX(B:B, MATCH("A002", A:A, 0)) | df.set_index("code").loc["A002", "price"] | 按键查值 |

| =INDEX(2:2, 3) 取第 2 行第 3 列 | df.iloc[1, 2] | 按位置查 |

| 按列名取整列 | df["price"] | |

lookup = pd.DataFrame({
    "code": ["A001", "A002", "A003"],
    "name": ["苹果", "香蕉", "橙子"],
    "price": [5, 3, 6],
}).set_index("code")

# MATCH 找到 code=A002 的行, INDEX 取 price
print("A002 价格 =", lookup.loc["A002", "price"])
# 按列名取整列
print("price 列 =", lookup["price"].tolist())
A002 价格 = 3
price 列 = [5, 3, 6]

注意事项:

  • loc 按标签索引,iloc 按位置索引。Excel 的 MATCH(..., 0)(精确匹配)对应 loc。
  • 如果 code 列有重复,loc["A002"] 会返回多行,需要再用 .iloc[0] 取第一个。

7. LEFT / RIGHT / MID ↔ str.slice

Excel 的 LEFT(A2, n) 取前 n 个字符,RIGHT(A2, n) 取后 n 个,MID(A2, start, n) 从第 start 位取 n 个。pandas 里直接用 Python 切片语法。

| Excel 公式写法 | pandas 等价代码 | 说明 |

|----------------|-----------------|------|

| =LEFT(A2, 3) | s.str[:3] | 前 3 个 |

| =RIGHT(A2, 3) | s.str[-3:] | 后 3 个 |

| =MID(A2, 2, 3) 从第 2 位起取 3 个 | s.str[1:4] | Python 切片从 0 开始,左闭右开 |

txt = pd.Series(["abcdefg", "1234567", "Python"])
print("LEFT 3:\n", txt.str[:3])
print("RIGHT 3:\n", txt.str[-3:])
print("MID 2,3 (从第2位取3个):\n", txt.str[1:4])
LEFT 3:      RIGHT 3:      MID 2,3:
0    abc    0    efg     0    bcd
1    123    1    567     1    234
2    Pyt    2    hon     2    yth
dtype: str   dtype: str    dtype: str
⚠️ 常见坑:Excel 的 MID(A2, 2, 3) 是"从第 2 位开始取 3 个"(1-based),pandas 的 s.str[1:4] 是"从索引 1 取到索引 4"(0-based,左闭右开)。换算公式:Excel MID(text, start, n) ≈ pandas s.str[start-1:start-1+n]。

8. IFERROR ↔ fillna / where / 掩码

Excel 的 =IFERROR(A2/B2, 0) 意思是:算 A2/B2,如果出错就返回 0。pandas 里除法本身不会"报错",而是产生 NaN 或 inf(旧版),用 fillna 兜底。

| Excel 公式写法 | pandas 等价代码 | 说明 |

|----------------|-----------------|------|

| =IFERROR(A2/B2, 0) | (a/b).fillna(0) | 出错填 0 |

| =IFERROR(A2/B2, "") | (a/b).astype(object).where(b!=0, other="") | 填字符串 |

| 屏蔽 0 除 | (a/b).where(b!=0) | 保持 NaN |

mixed = pd.Series([10, 0, 20, 0, 30], dtype="float64")
b = pd.Series([2, 0, 4, 0, 5], dtype="float64")

# pandas 3.0 中 Series 除以 0 直接得到 NaN(旧版会得到 inf)
ratio = mixed / b
print("原始除法:\n", ratio)

# 用 where 屏蔽 0,再 fillna 兜底
safe = ratio.where(b != 0, other=np.nan).fillna(0)
print("IFERROR 处理后:\n", safe)
原始除法:
 0    5.0
1    NaN
2    5.0
3    NaN
4    6.0
dtype: float64
IFERROR 处理后:
 0    5.0
1    0.0
2    5.0
3    0.0
4    6.0
dtype: float64
⚠️ 版本差异:pandas < 2.0 里 Series / 0 会得到 inf(无穷大),需要 replace([np.inf,-np.inf], np.nan).fillna(0);pandas 3.0 起 Series 除以 0 直接给 NaN,省一步。

9. RANK ↔ rank

Excel 的 =RANK(B2, B:B, 0) 是降序排名,=RANK(B2, B:B, 1) 是升序。pandas 里 s.rank() 有多个 method 控制并列值的处理方式。

| Excel 公式写法 | pandas 等价代码 | 说明 |

|----------------|-----------------|------|

| =RANK(B2, B:B, 0) 降序,并列取平均 | s.rank(ascending=False, method="average") | Excel 默认 |

| 并列名次连续(dense rank) | s.rank(ascending=False, method="dense") | 1,2,2,3 而不是 1,2,2,4 |

| 并列取最小名次 | s.rank(ascending=False, method="min") | |

r = pd.Series([90, 85, 90, 70, 100])
print("降序 rank (method=average):\n", r.rank(ascending=False, method="average"))
print("降序 rank (method=dense):\n", r.rank(ascending=False, method="dense"))
print("降序 rank (method=min):\n", r.rank(ascending=False, method="min"))
降序 rank (method=average):  [2.5, 4.0, 2.5, 5.0, 1.0]
降序 rank (method=dense):    [2.0, 3.0, 2.0, 4.0, 1.0]
降序 rank (method=min):      [2.0, 4.0, 2.0, 5.0, 1.0]
dtype 均为 float64

注意事项:

  • Excel 的 RANK 默认是"并列取平均"(两个 90 分并列第 2,下一个是第 4),对应 method="average"。
  • method="dense" 是比赛排名(1,2,2,3),method="min" 是中式排名(1,2,2,4),按业务需要选。

10. ROUND ↔ round

最简单的一个:=ROUND(A2, 2) 就是 s.round(2)。

| Excel 公式写法 | pandas 等价代码 | 说明 |

|----------------|-----------------|------|

| =ROUND(A2, 2) | s.round(2) | 保留 2 位 |

| =ROUND(A2, 0) | s.round(0) | 取整 |

| =ROUNDUP(A2, 0) / =ROUNDDOWN(A2, 0) | np.ceil(s) / np.floor(s) | 向上 / 向下 |

print(pd.Series([3.14159, 2.71828, 1.445]).round(2))
0    3.14
1    2.72
2    1.44
dtype: float64
⚠️ 常见坑:round(2) 用的是"银行家舍入"(四舍六入五成双),不是 Excel 的"四舍五入"。1.445 在上面结果是 1.44 而不是 1.45——因为浮点数 1.445 实际存储是 1.4449999...。要严格四舍五入用 Decimal 或 np.floor(x*100+0.5)/100。

11. CONCATENATE / TEXT ↔ str 拼接与格式化

Excel 的 =A2&"-"&B2 拼接,=TEXT(A2,"¥#,##0.00") 格式化。pandas 里是 str.cat 和 f-string。

| Excel 公式写法 | pandas 等价代码 | 说明 |

|----------------|-----------------|------|

| =A2&"-"&B2 | s1.str.cat(s2, sep="-") | 两列拼接 |

| =TEXT(A2, "¥#,##0.00") | s.map(lambda x: f"¥{x:,.2f}") | 货币格式化 |

| =TEXT(A2, "0.0%") | (s*100).round(2).astype(str) + "%" | 百分比 |

name = pd.Series(["张三", "李四"])
dept = pd.Series(["销售", "技术"])
print("拼接:\n", name.str.cat(dept, sep="-"))

money = pd.Series([1234.5, 6789.0])
print("格式化:\n", money.map(lambda x: f"¥{x:,.2f}"))
拼接:
 0    张三-销售
1    李四-技术
dtype: str
格式化:
 0    ¥1,234.50
1    ¥6,789.00
dtype: str

12. VLOOKUP 模糊匹配 ↔ merge_asof / pd.cut

Excel 的 =VLOOKUP(分数, 等级表!A:B, 2, TRUE) 是"按区间近似匹配"。pandas 里有两种场景:分段打标用 pd.cut,有序关联用 pd.merge_asof。

| Excel 公式写法 | pandas 等价代码 | 说明 |

|----------------|-----------------|------|

| =VLOOKUP(分数, 等级表, 2, TRUE) 分段 | pd.cut(s, bins=[0,60,80,100], labels=["不及格","及格","优秀"]) | 等宽分段 |

| 按时间近似关联 | pd.merge_asof(left, right, on="时间", direction="backward") | 时间序列常用 |

# 场景一:分数分段
score_bin = pd.Series([95, 55, 72, 40, 88])
bins = [0, 60, 80, 100]
labels = ["不及格", "及格", "优秀"]
cat = pd.cut(score_bin, bins=bins, labels=labels, include_lowest=True)
print("pd.cut 分级:\n", cat)

# 场景二:merge_asof 按时间近似匹配
left = pd.DataFrame({"time": [1, 3, 5, 7], "val": [10, 20, 30, 40]})
right = pd.DataFrame({"time": [1, 4, 6], "price": [100, 200, 300]})
m = pd.merge_asof(left, right, on="time", direction="backward")
print("merge_asof:\n", m)
pd.cut 分级:
 0     优秀
1    不及格
2     及格
3    不及格
4     优秀
dtype: category
Categories (3, str): ['不及格' < '及格' < '优秀']
merge_asof:
   time  val  price
0     1   10    100
1     3   20    100
2     5   30    200
3     7   40    300
💡 注意 merge_asof 的结果:time=3 时,right 里没有 time=3,向后找最近的 time=1 → price=100;time=7 时向后找 time=6 → price=300。这正是 Excel VLOOKUP 近似匹配的行为。

13. 综合案例:按部门汇总超预算金额

最后用一个综合案例把上面所有公式串起来。需求:

财务给了两张表:① 各部门月度预算;② 本月每笔实际支出。要求用 pandas 算出每个部门"实际支出 - 预算 = 超支金额",并标记"超支 / 节余"。
# 预算表
budget = pd.DataFrame({
    "dept": ["销售", "技术", "行政"],
    "budget": [5000, 8000, 2000],
})
# 实际支出表
actual = pd.DataFrame({
    "dept": ["销售", "销售", "技术", "技术", "技术", "行政", "行政"],
    "amount": [1200, 4500, 3000, 5000, 200, 1500, 800],
})

# 步骤 1: 按部门汇总实际支出(等价 SUMIFS)
act_sum = actual.groupby("dept", as_index=False)["amount"].sum().rename(columns={"amount": "actual"})
print("各部门实际支出:\n", act_sum)

# 步骤 2: 与预算合并(等价 VLOOKUP 把预算贴到实际表)
report = budget.merge(act_sum, on="dept", how="left").fillna({"actual": 0})

# 步骤 3: 计算超支 + 打标(等价 IF)
report["over"] = report["actual"] - report["budget"]
report["status"] = np.where(report["over"] > 0, "超支", "节余")
print("最终报表:\n", report)

# 步骤 4: 只看超支部门(等价 COUNTIF 的筛选版)
print("超支部门:\n", report[report["over"] > 0])
各部门实际支出:
   dept  actual
0   技术    8200
1   行政    2300
2   销售    5700
最终报表:
   dept  budget  actual  over status
0   销售    5000    5700   700     超支
1   技术    8000    8200   200     超支
2   行政    2000    2300   300     超支
超支部门(即 over>0 的行): 销售 700 / 技术 200 / 行政 300
💡 这个案例里:groupby+sum 替代了 SUMIFS,merge 替代了 VLOOKUP,np.where 替代了 IF,布尔索引替代了筛选——四步拼起来就是一张完整的财务报表。

14. 常见坑

⚠️ 坑 1:Excel MID 与 pandas 切片的偏移
Excel MID(text, start, n) 是 1-based,pandas s.str[a:b] 是 0-based 且左闭右开。换算:Excel MID(t, s, n) ≈ pandas t.str[s-1 : s-1+n]。

>

⚠️ 坑 2:pandas 3.0 除法不再返回 inf
旧版 pandas 里 Series / 0 会得到 inf,需要 replace([np.inf,-np.inf], np.nan) 清洗;pandas 3.0 起直接给 NaN,fillna(0) 一步到位。写兼容代码建议统一用 (a/b).replace([np.inf,-np.inf], np.nan).fillna(0)。

>

⚠️ 坑 3:np.where 返回 numpy 数组,不是 Series
np.where(s>0, 1, 0) 返回 numpy.ndarray,赋给新列没问题,但要继续调用 .str / .dt 等 pandas 访问器会报错。需要时用 pd.Series(..., index=s.index) 包回去。

>

⚠️ 坑 4:rank 的 method 选错导致排名错
Excel RANK 默认是 method="average"(并列取平均,如 2.5),不是 dense。如果你想要 1,2,2,3 这种比赛排名,必须显式写 method="dense"。

>

⚠️ 坑 5:GROUPBY 后列名变了
df.groupby("dept")["amount"].sum() 返回的是 Series,名字叫 amount;df.groupby("dept", as_index=False)["amount"].sum() 才是 DataFrame。要继续 merge 时记得加 as_index=False。

15. 本章小结与练习题

小结

1. Excel 公式在 pandas 里几乎都有一一对应:SUMIF/SUMIFS↔布尔索引+sum / groupby、COUNTIF↔布尔求和、IF↔np.where、IFS↔np.select、INDEX/MATCH↔loc、LEFT/RIGHT/MID↔str 切片、IFERROR↔fillna、RANK↔rank、ROUND↔round。

2. 核心差异:Excel 公式逐格求值,pandas 整列向量化;写 pandas 代码要从"格子思维"切换到"列思维"。

3. 多分支用 np.select,不要用 apply(lambda row: ...)——向量化快几十倍。

4. 分段打标用 pd.cut,时间近似关联用 pd.merge_asof,是 Excel VLOOKUP 模糊匹配的两个标准替代。

练习题

1. 给定 df = pd.DataFrame({"dept":["销售","技术","销售"],"amount":[100,200,300]}),分别用 (a) 布尔索引+sum、(b) groupby+sum 两种方式算出"销售部门总金额",并对比代码长度。

2. 用 np.select 实现:成绩 ≥90 为"优",≥75 为"良",≥60 为"及格",否则为"不及格"。写出完整代码并测试 [95, 80, 65, 50]。

3. 把 Excel 公式 =IFERROR(VLOOKUP(A2, 客户表!A:B, 2, FALSE), "未知") 翻译成 pandas 写法(提示:merge 后 fillna)。

4. 给定 s = pd.Series([88, 92, 88, 70, 100]),分别用 method="average"、"dense"、"min" 计算降序排名,解释三个结果的差异。

5. 用 pd.cut 把 [25, 45, 60, 75, 90] 分成三段:<30 青年、30~60 中年、>60 老年,并写出 labels。

6. (综合题)扩展第 13 节的财务案例:再加一列"预算使用率 = actual / budget",用 map 格式化成百分比字符串(保留 1 位小数),并按使用率降序排序输出。


下一篇预告:第 51 章 LeetCode pandas 题库精讲(一) —— 用 LeetCode DataFrame 真题把前面学过的过滤、合并、聚合练到肌肉记忆。
— 全文完 —回到顶部 ↑
下载推广海报

文章推广海报

《第 50 章 Excel 公式与 pandas 对照》完整推广海报
DISCUSSION

文章回复

0 条公开回复
未登录回复需要审核后公开
还没有回复,欢迎参与讨论。