表格里躺着八百行数据,用眼睛看看到眼花。今天请来数据分析界的”重型吊车”——
pandas,一行代码把整张Excel读进程序,列名直接当标签用,求和、平均、找最大值都不用写循环
一、老板的三个问题
先说一个你迟早会遇到的场景。
周五下午五点五十,老板在群里甩过来一个销售明细.xlsx:”帮我看看,今年总销售额多少?谁卖得最多?平均一单多少钱?快点,六点开会要用。”
你打开文件——八百行,十七列。你点进”销售额”这一列,Excel左下角状态栏显示求和;再排序找最大值对应的销售名;再用AVERAGE算平均。三个问题,三轮操作,五分钟。刚喘口气,老板又来了:”那按月看看呢?华东区单独算呢?”——每多一个问题,就是一轮手动操作。
问题出在哪?数据在表里躺着,但你每次提问都要”手动翻一遍”。翻一次五分钟,翻十次就误了饭点。
如果数据在程序里呢?每个问题就是一行代码,问得再快也答得再快:
print("总销售额:", df["销售额"].sum())
print("销售冠军:", df.loc[df["销售额"].idxmax(), "姓名"])
print("平均单值:", df["销售额"].mean())
df是什么?sum()是什么?idxmax又是什么?别急,今天就从零开始认识它们。今天的唯一一个新概念就是:pandas——一个专门对付表格数据的Python工具箱。其他的(.sum()、.mean()这些)都是”它自带的小工具”,看一遍就会用。
二、新朋友:pandas——表格数据的”万能工作台”
pandas(名字来源于”panel data”面板数据,跟熊猫没有半毛瓜葛,虽然它的logo就是熊猫)是Python世界里数据分析的头号工具箱。Excel能干的事它能干,Excel干不动的(百万行、自动批处理、跟程序逻辑混着用)它也能干。
第25到29篇我们用csv模块手搓过表格读写——一行一行读、一个个字段拆、自己写循环统计。那些活pandas统统一行搞定。它不是标准库,得先安装:
pip install pandas openpyxl
两个都要装:pandas是主角,openpyxl是它读Excel文件的”引擎”(读.xlsx专用,不装的话pandas张开嘴却咬不动Excel)。只读CSV的话不用装openpyxl。
装好后,第一行代码永远是这句:
import pandas as pd
as pd是给模块起外号——pandas全名太长,后面敲pd就够了。这是全世界Python程序员的统一惯例,你写import pandas as pandas语法上没错,但别人会投来异样的眼光。
DataFrame:程序里的”超级表格”
pandas最核心的数据结构叫DataFrame(数据框),你可以把它理解成一张住在程序里的Excel表:有行、有列、有列名。读Excel文件的函数是pd.read_excel():
import pandas as pd
df = pd.read_excel("销售明细.xlsx")
print(df)
跑起来是这样(我造了五行假数据演示):
姓名 部门 销售额 日期
0 小王 华东 12000 2026-01-05
1 小李 华南 8500 2026-01-06
2 小张 华东 15300 2026-01-07
3 小赵 华北 9200 2026-01-08
4 小王 华东 11000 2026-01-09
看见没——pd.read_excel()一个函数,整张表进来了,姓名、部门、销售额、日期四个列名都保留着,左边还自动多了一列0、1、2、3、4,那是pandas给每行编的行号(专业名叫”索引”,index)。
顺手记一下:CSV文件同理,把函数名换一下就行:
df = pd.read_csv("销售明细.csv") # 第25篇手搓的那个csv,pandas一秒读完
读Excel用read_excel,读CSV用read_csv——一个函数一张表,这就是pandas的见面礼。
三、读懂DataFrame:先”看”,再”问”
拿到df之后,第一件事不是闷头算,而是先看清楚表长什么样。就像拿到一摞报销单先翻翻抬头,别上来就加总。pandas给了三个”看”的小工具:
print(df.head()) # 瞄前5行(默认5行,head(10)看10行)
print(df.shape) # 几行几列 → (800, 4) 表示800行4列
print(df.columns) # 所有列名 → Index(['姓名', '部门', '销售额', '日期'], dtype='object')
shape返回一个两个元素的元组(跟第30篇os.path.splitext返回的元组一个脾气):(行数, 列数)。注意它没有单位,你得自己记住”第一个是行”。看一眼shape再动手,是老手的习惯——表有没有读对、行数对不对,这一眼就见分晓。
取一列:列名就是”标签”
Excel里你点C列的列头选中整列;pandas里用方括号加列名:
销售额们 = df["销售额"]
print(销售额们)
0 12000
1 8500
2 15300
3 9200
4 11000
Name: 销售额, dtype: int64
df["销售额"]返回的东西叫Series(系列),你可以理解成”一列数据”。它带着原来的行号,也带着自己的名字Name: 销售额。DataFrame是整张表,Series是其中一列——记住这一句,后面所有pandas代码你都能看懂”现在手上拿的是什么”。
一列直接算:求和、平均、找最值
最爽的部分来了。拿到Series之后,统计函数直接”长”在它身上:
print(df["销售额"].sum()) # 800行求和 → 9654300
print(df["销售额"].mean()) # 平均值 → 12067.9
print(df["销售额"].max()) # 最大值 → 15300
print(df["销售额"].min()) # 最小值 → 8500
print(df["销售额"].count()) # 非空的有多少个 → 5
回想第26篇我们怎么算CSV总销售额的?total = 0,for循环一行行加,还得float()转换、try/except防脏数据。现在呢?df["销售额"].sum()——一个属性取列,一个函数求和,循环、转换、累加,pandas全替你干了。这就是”一行顶十行”。
这里有个隐藏知识点顺嘴说清:df["销售额"]是一列,.sum()是这一列自带的函数。整个链条读法是”表的销售额列,求和”——从左往右念人话,这是读懂pandas代码的诀窍。以后见到df["部门"].unique()(部门都有哪些不重复的值)、df["姓名"].nunique()(多少个不同的人),你也能猜个八九不离十。
四、实战:三个问题一分钟出答案
好,工具齐了,回去收拾老板的三个问题。完整代码:
import pandas as pd
# 1. 读表(先"看"再"问"的老规矩)
df = pd.read_excel("销售明细.xlsx")
print(f"表读进来了:{df.shape[0]}行 × {df.shape[1]}列")
print("列名:", list(df.columns))
print(df.head())
# 2. 老板的三个问题
print("——————————")
print("问题1,今年总销售额:", df["销售额"].sum())
print("问题2,销售冠军是:", df.loc[df["销售额"].idxmax(), "姓名"])
print("问题3,平均一单:", round(df["销售额"].mean(), 2), "元")
# 3. 顺便多给两句,显得专业
print("——————————")
print("最低一单:", df["销售额"].min(), "元")
print("共有订单:", df["销售额"].count(), "单")
输出:
表读进来了:800行 × 4列
列名: ['姓名', '部门', '销售额', '日期']
——————————
问题1,今年总销售额: 9654300
问题2,销售冠军是: 小张
问题3,平均一单: 12067.88 元
——————————
最低一单: 8500 元
共有订单: 800 单
问题2那行最”吓人”,拆开看其实是三句人话:
df["销售额"].idxmax() # 最大值在第几行(行号)
df.loc[行号, "姓名"] # 取那一行的"姓名"格子
idxmax()返回最大值所在的行号,df.loc[行号, 列名]按行号列名取一个格子——就像Excel里”先定位到最大值在哪行,再读那行的姓名列”。loc是”location(位置)”的缩写,方括号里第一个是行、第二个是列,逗号隔开。今天先照抄用着,第32篇会让你看到它的更多花样。
以后老板再追加问题,你加一行代码就好:”按月看”——等下一篇;”华东区单独算”——也是下一篇。问题变多,代码只增不改,这就是”数据进了程序”和”数据锁在Excel”的本质区别。
五、四个必踩的坑(先打疫苗)
坑1:pandas不是自带的,还差一个引擎。 最常见的报错长这样:
ImportError: Missing optional dependency 'openpyxl'
翻译:pandas读Excel需要openpyxl这个引擎,你没装。pip install openpyxl一发解决。反过来只装了openpyxl没装pandas,那连pd都import不进来。两个都装,一个负责大脑一个负责牙齿。
坑2:一张Excel里的”好几张表”。 Excel文件可以有多个工作表(Sheet),read_excel默认只读第一张。如果数据藏在叫2026明细的第二张表里,你读回来的df可能只有封面那几行,还纳闷数据怎么不对。两种应对:
# 办法1:指定表名或表序号(0是第一张,1是第二张)
df = pd.read_excel("销售明细.xlsx", sheet_name="2026明细")
df = pd.read_excel("销售明细.xlsx", sheet_name=1)
# 办法2:先看看这文件里都有哪些表
print(pd.ExcelFile("销售明细.xlsx").sheet_names)
开工前先看sheet名单,跟第30篇”先glob盘点再动手”是一个道理——先摸清地形,再开推土机。
坑3:表头不在第一行。 很多人的Excel前两行是大标题(”2026年度销售明细汇总表”),第三行才是姓名/部门/销售额。pandas默认把第一行当列名,结果列名变成了一堆Unnamed: 1(无名列)。改法是指定表头在第几行(从0数):
df = pd.read_excel("销售明细.xlsx", header=2) # 第3行才是表头
如果表尾还有一行”合计”,它会被当成普通数据混进来,读完head()和tail()(tail看最后5行,head的孪生兄弟)各瞄一眼,两头的妖魔鬼怪都现形。
坑4:空单元格会变成NaN,混进数字列里捣乱。 Excel里留空的格子,读进来是NaN(Not a Number,”不是数”)。好消息:sum()、mean()会自动跳过NaN;坏消息:count()只数”非空”,所以”有800行但count()只有796″是正常的——那4行是空的。更坏的消息:如果”销售额”列里混了文字(比如有人手滑写了约300或12000元),整列会被pandas当”文本列”处理,.sum()直接报错unsupported operand type。这一列的”清洗”怎么干,第29篇的思路直接复用:读进来先print(df["销售额"].dtype)(看这一列的类型,数字列显示int64/float64,文本列显示object),不对劲就先洗再算。
六、跟AI协作的正确姿势(pandas特供)
pandas是出了名的”功能多到看不完”,恰好是AI的主场。但指挥有三个要点:
- 把表的”长相”贴给AI。别说”帮我用pandas分析Excel”,说”表有800行4列,列名是
姓名、部门、销售额、日期,销售额是整数,日期是日期格式,我想算总额、找销售冠军、算平均单值”——贴上df.head()的输出,AI给的代码就不会猜错列名(它最爱瞎编df['sales']这种列名) - 先要”只读探路”,再要”正式分析”。第一条需求永远是:”先给我一段’体检代码’,读表后打印行数、列名、每列类型和前5行,不要做任何计算“。表读对了,后面全对;表读错了,后面全白干
- 让它把”魔法链”拆开讲。pandas一行能叠三层:
df[df["销售额"] > 10000]["姓名"].unique()。看到这种代码别硬啃,直接问:”这行拆成一步一步的中间变量写法,并解释每一步“。拆开看,无非是”筛选行→取列→去重”,都是学过的人话
高频句式送你:”我有一个Excel,列名是……,每列的数据类型是……。请先给我读表+体检的代码(只打印不计算),我确认表读对后,再帮我写’某某问题’的分析代码,要求每一步都写注释解释“——把这句丢给AI,出来的代码你能看懂、能改、能留着复用。
七、今日小练习
练习1:把”三个问题”改成能问十次
把实战代码包进一个while True循环:每次打印”请输入要看的列名(q退出)”,输入列名就打印该列的sum/mean/max/min四个统计;输入q退出。(提示:input()拿到的是字符串,正好当df[列名]的钥匙用;退出前先判断if 列名 == "q",再判断if 列名 in df.columns防止列名写错报错——第10篇异常处理的思路,其实用in判断更优雅。while True:里记得留好退出口,不然程序停不下来。)
练习2:多表读取小能手
一个文件夹里躺着1月.xlsx、2月.xlsx……12月.xlsx十二个文件,列名一致,算出全年总销售额和每个月的销售额。(提示:第30篇的glob.glob("*.xlsx")找出所有文件,for循环里逐个pd.read_excel、逐个.sum()累加进一个字典——又是第26篇”字典计数”的老套路,只是这次存的是求和。打印时想按1、2、3…12月排?sorted(文件们)先把列表排好序再循环。)
练习3:给表做张”体检小结”
读任意一个Excel,打印一份体检报告:行数列数、列名清单、每列的数据类型、每列有多少个空值(NaN)、数字列的平均值。(提示:单列类型用df["列名"].dtype;数空值用df["列名"].isna().sum()——isna()返回每行”是不是空”的True/False列,.sum()把True当1加起来,正好是空值个数。想一把梭的话,df.describe()直接吐出所有数字列的”体检表”(计数、平均、标准差、最小四分位最大),先跑一遍看看它长什么样。)
写在后面:表格数据的”正餐”开席了
盘点今天:pandas是表格数据的万能工作台,DataFrame是住在程序里的超级表格;pd.read_excel()/pd.read_csv()一行读表;head/shape/columns先”看”再”问”;df["列名"]取一列成Series;sum/mean/max/min/count统计直接长在列上;df.loc[行, 列]按坐标取格子。
更值钱的是思路升级:从今天起,表格数据的标准动线是”读进程序→看清长相→按需提问“。在Excel里,每个问题都是一次人工翻找;数据进了pandas,每个问题都是一行代码——问一百次也只要一百行,而且隔周还能原样再跑一遍。能被反复提问的数据,才是真正活起来的数据。
下一篇,筛选和排序登场:df[df["部门"] == "华东"]一行筛出华东区,sort_values一行排好序——”华东区销售额前十名是谁”这种问题,两行代码拿下。
下篇预告
第三十二篇:Excel筛选排序——pandas的筛选魔法:一行代码筛出”华东区、销售额过万、三月份”的订单,再按销售额排个序。Excel要点十几下鼠标的事,pandas眨眨眼。
发表回复