1. 从一次小组作业谈起:为什么我建议先跑通“读Excel + 画图”
前几天有朋友问我,说想学数据分析,但打开一堆教程全是术语,什么Series、DataFrame、透视表,还没开始就劝退了。我让他先别管那些概念,直接打开一个真实的Excel文件,用pandas把你最关心的那几列读进来,再挑一列画个图,看看数据长什么样。跑通这一步,比抱着书啃三天都有用。这篇博文要聊的,就是这条人人都能上手的入门路线:用pandas读取excel,然后基于读进来的数据完成一次最基础的绘图。
为什么拿Excel当第一个战场?因为大多数人手头都有现成的Excel文件,可能是课程作业表、部门值班表、某个月的销售记录,甚至是一份乱七八糟的通讯录。它不需要你去连数据库,不需要写SQL,只要文件路径没错,pandas一行代码就能把表格搬进Python。而且Excel这种“二维表”结构天然贴近DataFrame的形态——行是记录,列是字段,理解成本极低。等你在Excel上把读取、筛选、统计、画图这套流程走熟了,再去接触CSV、JSON、数据库导出文件,会发现底层逻辑完全一样,只是入口换了一下。
这篇文章适合三类人:刚学Python但不知道拿它做什么的学生,日常工作要处理报表但不想手动复制粘贴的职场人,以及想系统入门数据分析但被各种概念吓住的自学者。我会把环境怎么搭、read_excel怎么用、空值怎么处理、图表怎么画、常见的坑怎么避,全部用大白话加实操代码拆开讲。跟着敲一遍,你手里的Excel文件就能变成一张张有用的图。
2. 思路先理顺:pandas在数据分析里的位置,以及它的“读、看、改、画”四步节奏
2.1 为什么选pandas而不是直接写Python原生代码
很多人第一次接触pandas会觉得它是一个很“重”的库,装下来几百MB,导入还要等一两秒。其实它的价值就藏在那种“等一下”里。pandas底层是numpy,也就是用C语言实现的高性能数组计算,而它自己在numpy外面又包了一层“表格逻辑”——给你行列索引、分组聚合、缺失值处理、时间序列这些日常操作。你直接用Python原生列表和字典也能做数据处理,但一旦列多了、行数上万了,原生代码会变得又慢又啰嗦,而pandas往往一行就搞定,运维同学和业务同学都能看懂。
Excel文件本质上是二进制格式(xlsx是ZIP压缩包里的XML,老版本xls是OLE2复合文档),Python原生根本没法直接解析。pandas在读取时会把Excel里的单元格解析成Python对象,数值归数值,字符串归字符串,日期自动变成时间类型,整个解析过程不需要你碰底层文件格式。这也是为什么我入门时总跟人说:不要用openpyxl手动逐行读Excel再手动算统计,那是给自己挖坑。pandas已经帮你把路铺好了,你要做的是学会踩上去。
2.2 读、看、改、画:一条可以复用的数据处理节奏
我自己处理任何一张新表,基本都按“读、看、改、画”四步走。第一步“读”很简单,pandas读取Excel文件,把结果赋给一个变量;第二步“看”特别关键,但不是让你从头到尾滚动看,而是用head()看前几行,用info()看每列类型和缺失情况,用describe()看数值列的统计摘要,这几行命令能让你在30秒内知道这张表“大概是什么质量”;第三步“改”,包括改名、补缺失值、转换日期类型、删除不想要的列,属于预处理环节;最后一步“画”,基于清洗好的数据调用plot()或Matplotlib画图,把规律和异常用视觉呈现出来。
初学者最常见的毛病是跳过“看”,读完表直接上手算,结果算出来的结果跟Excel里对不上,还怀疑是程序错了。其实90%的对不上都是数据本身的问题——空值被当成0了、日期列被读成字符串了、有隐藏的合并单元格被解析出空行。把“看”这步养成肌肉记忆,后面所有问题都能提前暴露。接下来我会按照这四个步骤,用一张模拟的销售表作为例子,一步步带你走完。
3. 环境准备与Excel读取全拆解:从安装库到read_excel的每个参数
3.1 先花三分钟把环境装好
在用pandas读取Excel之前,需要确认你的Python环境里至少有三个库:pandas、matplotlib、openpyxl。pandas负责读表和数据结构,matplotlib负责绘图,openpyxl是pandas背后真正解析xlsx文件的引擎。很多人只装了pandas就去读Excel,结果报错说缺少引擎,错得非常冤。安装命令很简单,直接在终端或命令行执行:
pip install pandas matplotlib openpyxl如果你用的是Anaconda,其实前两个已经预装了,只需要检查一下openpyxl:
conda install openpyxl装完后建议用一个新建的目录放代码和Excel文件,比如“pandas_study”,把要读的表格也丢进去。这样可以避免后面写路径时出现一堆“C:\Users\xxx\Downloads\xxx.xlsx”之类又长又容易错的东西。我甚至建议你把这个目录拖到编辑器的工作区里,然后用相对路径读文件,代码可读性会高很多。
3.2 read_excel到底有哪些参数值得记
pandas读取Excel的核心函数是pd.read_excel,很多人只用了它的第一个参数(文件路径),遇到复杂一点的需求就不知道怎么处理了。我挑几个最常用的参数给你梳理一遍,每个都配一个使用场景,你以后看到别人的代码也能瞬间明白在干什么。
第一个是sheet_name,用来指定读取哪个工作表。它可以接收工作表的名字(字符串),也可以接收工作表的位置(整数,0表示第一个工作表),甚至传一个列表,一下子读多个工作表。比如你要读“2024年销售记录”这个sheet,直接写sheet_name="2024年销售记录"即可。最容易被忽略的是如果你不传这个参数,pandas默认读第一个工作表。我遇到过好几回,文件里明明有多个sheet,结果默认读到的是“目录”页,里面全是说明文字,后面怎么处理都不对。所以建议每次都显式指定sheet_name。
第二个是header,指定用哪一行作为列名。默认header=0,就是用第一行当作列名。有些表格第一行是大标题,第二行才是真正的字段名,这时候你就要header=1。有些表压根没有字段名,全是数据,那你就header=None,读取后pandas会自动生成0、1、2这样的列名。这个参数看起来简单,但用错了会让后面所有引用列名的代码全部报错,属于排查成本较高的一个点。
第三个是usecols,用来只读某几列。比如一个表有20列,你只需要“日期”和“销售额”,就写usecols=["日期", "销售额"],或者用Excel列名的方式usecols="B:D"。这个参数的价值在两点:一是让内存吃得少,二是避免无关列干扰你判断。尤其是有些表格里带着一堆公式计算列,读进来会变成无效值,只读你需要的列反而更干净。
第四个是dtype,用来指定某些列的数据类型。比如你有一列“工号”,Excel里是数字,但工号本身没有数学意义,如果让它以整数读入,后面所有操作都是数字语义,容易误算;更麻烦的是有些长数字会被Excel自动转成科学计数法。你可以这样写dtype={"工号": str},强制读成字符串。同理,如果某列是日期时间,你可以不在这里处理,后面用parse_dates统一搞定。
第五个是parse_dates,这个参数可以直接把Excel里读到的日期文本转成pandas的datetime类型。比如parse_dates=["下单时间"],读取的时候就会自动转换。日期类型非常重要,xlsx原本存的是日期格式,pandas读进来可能是datetime64,但如果表格里有个单元格是纯文本写的日期,就可能变成object类型。后面你想按月份汇总,如果是datetime类型可以直接用dt属性,短代码一行搞定;如果是object,你还得再转一次。所以读取阶段能转就转。
第六个是engine,指定读取引擎。读xlsx默认用openpyxl,读xls要用xlrd,读xlsm需要注意版本兼容。这个参数一般不用写,但如果你遇到版本冲突的报错,知道有这个东西就能快速定位方向。
最后再补一个skiprows,跳过文件开头若干行。有些表前面有两三行版权说明、标题备注,真正表头从第4行开始,那就skiprows=3。注意这个和header的逻辑要注意配合,别跳多了把自己的列名跳没了。
3.3 一个完整的读取示例
先别急着背参数,我带你从头到尾写一遍。假设你手上有一个文件“销售数据.xlsx”,里面有一个工作表叫“销售记录”,表头是:日期、产品、地区、销售额、成本。要把它完整读进pandas,代码长这样:
import pandas as pd df = pd.read_excel( "销售数据.xlsx", sheet_name="销售记录", header=0, parse_dates=["日期"], dtype={"产品": str, "地区": str} ) print(df.head())运行之后,你会看到前五行数据。如果输出没有问题,说明读取成功。这里的print(df.head())就是“看”的第一步,很重要,我稍后会专门展开。
如果你手上是那种表头在第二行、前面还带说明文字的文件,比如前两行是标题和备注,第三才是字段名,那么读取代码改成:
df = pd.read_excel( "销售数据.xlsx", sheet_name="销售记录", skiprows=2, header=0, parse_dates=["日期"], dtype={"产品": str, "地区": str} )注意skiprows=2表示跳过前两行,然后header=0表示将接下来文件的第一行(也就是原文件的第3行)作为列名。你要是跳过3行,就会把真正的表头跳过,等同把数据第一行当列名,后面引用列名时会特别痛苦。遇到这种文件,我的建议是先不写skiprows,直接用head()多看几行,确认表头在哪,再回来改参数。
还有更进阶的用法,比如一次读多个sheet:pd.read_excel(..., sheet_name=["销售记录", "退货记录"]),返回的是一个字典,键是sheet名,值是各个DataFrame。日常报表经常有“详表+汇总表”的结构,这个功能能让你同时把两张表读进来,后面用merge或concat拼起来分析,非常方便。不过对刚入门的朋友,我建议先用单个sheet跑通,多sheet的读取技巧到了真实项目里再用,不然容易把基础流程搞混。
4. 读进来之后先别急:30秒数据体检与预处理操作详解
4.1 用head、info、describe快速体检
数据读进来了,第一步绝对不是直接算结果,而是做一次“体检”。我会依次运行三条命令,这三条命令之间层层递进:head看头,info看病,describe看数值概貌。先把这三条命令的代码放出来:
print(df.head()) df.info() print(df.describe())head()默认显示前5行,我要看的是“列名是不是我预期的”“表头有没有被读歪”“前几行数据是不是一堆NaN”。比如你明明有一列叫“销售额”,结果head()出来列名变成了“销售额.1”,说明Excel里有两个同名列,pandas自动给后面那个加了后缀。这时候如果不处理,后面按“销售额”取列,取到的可能不是你想要的。info()会列出每一列的名字、非空值数量、数据类型,这是找出“空值坑”和“类型坑”的利器。describe()只对数值列输出统计,包括均值、标准差、最小最大、四分位数。很多人不管三七二十一先describe,结果发现全是字符串列,输出只有一个count,其实没什么用,所以我提醒你,先head再info再describe,顺序别乱。
我自己的习惯是这三条命令写成一个小函数,每次读表直接调用,省得敲三遍:
def quick_view(df, n=5): print(df.head(n)) df.info() print(df.describe()) print(df.isna().sum())第四行的isna().sum()统计每列缺失值的数量,是在info基础上更进一步——info只说“非空数量”,isna把缺失数量精确列出来,哪个列缺多少一眼就能看出来。这个方法我用了五年,依然觉得是数据分析第一步里性价比最高的操作。
4.2 缺失值处理:dropna、fillna、ffill之间的选择
体检之后最常见的问题就是空值。Excel里空单元格读进pandas后会变成NaN,它跟0不一样,跟空字符串也不一样。最坑的是,有些操作在NaN参与下会静默返回错误结果,比如对一个含NaN的列求和,默认会忽略NaN,你把NaN当成0,可能刚好碰巧对上,但一旦你计算均值、占比,忽略NaN和用0填充的结果就会差很多。所以第一步要明确自己的处理策略,而不是让pandas替你默认选一个。
空值处理一般有三个方向。如果空值所在行本身没有分析价值,比如一行里关键字段几乎都是空的,那就直接删掉,用df.dropna(subset=["销售额"], inplace=True),意思是以“销售额”这列为准,只要它是空就把整行删掉。注意不要无脑dropna(),它会删除任何列有空值的行,可能把你的有效数据误伤一大片。
如果空值只是局部缺,比如前几行的日期缺失但后面都有,你可以用前向填充,也就是用上一行的值填充当前行的空值:
df["日期"] = df["日期"].ffill()这个操作在处理时序数据时特别有用。比如Excel表里因为合并单元格的原因,日期只填在每组的第一个单元格,其余往下全是空的,这种表如果你不做填充,后面按日期分组时,这些行全都会被归到缺失组里,统计结果直接作废。ffill()就是这种场景的标准解法。
如果空值本身意义不大,也可以用固定值或统计值填充,比如用均值填充销售额空值:
df["销售额"] = df["销售额"].fillna(df["销售额"].mean())但我要提醒一句,均值填充只适用于“缺失比例很低且数据分布比较均匀”的情况。如果你的销售额有明显的高低峰,比如工作日低、节假日高,用均值填充会抹掉波动特征,画出来的图会“假平”。更谨慎的做法是先算每组的均值,然后分组填充。这块内容在真实项目里很容易被忽视,新人踩坑频率很高,我想强调一下,别图省事直接mean()一把梭。
4.3 类型转换:日期与数值列的规范化处理
Excel表格来自不同的人,格式千奇百怪。常见的就是日期列读进来是object类型(因为你表格里混着“2024-01-01”“2024/1/1”“20240101”三种写法),或者数值列读进来变成了object(因为有“1,200”这种带千分位的写法)。这种时候就要手动做类型转换。
日期列统一转换用pd.to_datetime,一行代码:
df["日期"] = pd.to_datetime(df["日期"], format="mixed", errors="coerce")format="mixed"是让pandas自己猜测多种格式,errors="coerce"表示如果某个格子的日期实在解析不了,就置为NaT(缺失时间),而不是让整个程序崩溃。你可能会问,那解析不了的行怎么办?留着不处理,后面会拖累分组,建议根据实际情况删掉。数值列的处理类似:
df["销售额"] = ( df["销售额"] .astype(str) .str.replace(",", "", regex=False) .astype(float) )先转成字符串,把千分逗号去掉,再转成浮点数。这个套路看起来绕,但其实很安全,比直接astype(float)少踩很多隐蔽的报错。做这一步的时候,我会在转换后立刻用info()复查一遍,确认类型从object变成了datetime64或float64,要是发现还是object,说明数据里还有脏值,得继续排查。
整理完的这些步骤,才是为画图打基础。很多教程直接从读取跳到画图,画出来一堆乱线,然后说“pandas画图不好用”,其实根本是数据没洗干净。后面的图能不能讲清楚业务问题,前面的数据质量至少决定了一半。
5. 用pandas自带绘图画第一张图:plot的用法与一个完整的入门案例
5.1 为什么要先学plot而不是直接学matplotlib
pandas的DataFrame自带一个plot方法,本质是matplotlib的封装。你不需要先学一堆plt.subplot、ax.set_xlabel,只需要一行df.plot(),pandas就会根据你的数据自动生成一张线图或柱状图。这对初学者的最大价值是“低门槛反馈”——数据一读一画,结果马上就出来了,能极大提升继续学下去的信心。等你对图表的基本要素有感觉了,再回去学matplotlib的面向对象接口,会轻松很多。我见过不少人一上来就学matplotlib的各种底层概念,学了一个月还是画不出能用的图,反而挫败感很强。
pandas的plot支持常见图表类型,kind参数可以选:line折线图、bar柱状图、barh横向柱状图、hist直方图、box箱线图、pie饼图、kde密度图等。此外还支持分组绘图,比如df.groupby("产品")["销售额"].plot()就能画多条线。我平常用的最多的是line、bar、hist这三种,分别对应趋势、对比、分布三类最常见的分析需求,新人先掌握这三种就够用了。
5.2 完整案例:从Excel到一张能说明问题的柱状图
下面我用一个模拟场景把从读取到绘图的完整流程串起来。假设你是某地一个连锁门店的数据管理员,手上有一份“门店销售表.xlsx”,记录了2024年各门店每月的销售额、成本和利润。目标很明确:把“每个门店的月度总销售额”画成柱状图,看哪几家门店贡献大,哪几家需要重点盯。代码可以这样分层写:
import pandas as pd import matplotlib.pyplot as plt # 第一步:读取数据 df = pd.read_excel( "门店销售表.xlsx", sheet_name="销售明细", parse_dates=["日期"], ) # 第二步:体检 print(df.head()) df.info() # 第三步:缺失处理(示例:删除销售额为空的行) df = df.dropna(subset=["销售额"]) # 第四步:提取月份字段 df["月份"] = df["日期"].dt.to_period("M") # 第五步:按门店和月份汇总销售额 summary = df.groupby(["门店", "月份"])["销售额"].sum().reset_index() print(summary.head(10))到了这里,summary就是一个干净的门店月度汇总表。接下来画一个每家门店全年销售额加总的对比图:
total_by_store = summary.groupby("门店")["销售额"].sum().sort_values() total_by_store.plot(kind="bar", figsize=(10, 6), title="2024年各门店销售额对比") plt.show()代码走完,你会看到一张横向或者纵向的柱状图。可能有人会问,为什么这里用groupby两次,而不是简单地对原数据分组?因为我们先做了门店+月份的细分汇总,把日期粒度统一了,再做门店维度的汇总,逻辑更清晰,也方便后面改画“各门店月度趋势”。也许你觉得第一次就能直接画出来,实际上在真实场景里,先确认理解数据粒度再画图,才能避免画出“看似正确实际错误”的图。
5.3 常用图表参数与中文字体问题
pandas的plot方法有几个高频参数值得掌握:figsize控制画布大小,传元组比如(10, 6);title设置图标题;grid控制是否显示网格线;rot控制x轴刻度文字旋转角度,比如rot=45,避免日期或店名重叠;legend控制是否显示图例。真正常见的问题是中文显示——Windows上运行可能会显示成方块,是因为matplotlib默认字体不支持中文。解决方案是在画图之前设置中文字体:
import matplotlib as mpl mpl.rcParams["font.sans-serif"] = ["SimHei"] # Windows常见黑体 mpl.rcParams["axes.unicode_minus"] = False # 解决负号显示成方块的问题如果你用的不是Windows,字体名可能要换成“WenQuanYi Zen Hei”或“PingFang SC”,具体取决于系统装了什么字体。如果你不想写这些rcParams,也可以用plt.rcParams,效果一样。设置之后记得重新运行画图代码,不需要重启Python。我踩过几次坑之后,现在都会在任何画图代码开头先写这两行,不用管系统是什么,反正写了没坏处。
再补充一个保存图片的技巧。有时候你要把图放到工作汇报里,那就不只是plt.show(),还得保存成图片文件:
fig = total_by_store.plot(kind="bar", figsize=(10, 6), title="2024年各门店销售额对比") fig.figure.savefig("门店销售额对比.png", dpi=150, bbox_inches="tight")dpi=150是清晰度,bbox_inches="tight"会自动裁剪多余空白边,避免图片周围一圈白边。这个看起来很小的细节,会让你的图片在PPT里显得专业很多。
5.4 为什么我建议再画一张“趋势图”验证业务判断
柱状图能看出“谁多谁少”,但看不出“逐月怎么变化”。比如两张柱状图都很高,可能一家是每个月都稳定高,一家是前半年很差、后半年冲上来的。这两种情况风险完全不同,后者可能跟促销节奏有关。所以画完成对比图之后,我一般还会画一张折线趋势图。依然基于summary数据:
pivot_table = summary.pivot_table(index="月份", columns="门店", values="销售额") pivot_table.plot(kind="line", figsize=(12, 6), marker="o", title="各门店月度销售趋势") plt.show()pivot_table把行设为月份、列设为门店、值是销售额,相当于把一个长表转成了宽表。然后plot(kind="line")会自动为每家门店画一条线。marker="o"让数据点显示小圆点,便于看清每个月的具体数值位置。这张图能立刻帮你判断:某些门店是稳步上升还是断崖下跌,有没有季节性规律。我平时分析数据,至少会画一张对比图加一张趋势图,两张图交叉验证,结论才敢写进报告里。
6. 常见问题与排查技巧实录:那些文档里不会明说的坑
6.1 高频问题对照表
我见过太多人卡在同样的问题上,专门把高频坑整理成一个速查表。初学者不妨直接收藏,遇到报错先来这里找位置:
| 问题现象 | 可能原因 | 解决思路 |
|---|---|---|
| 读取时报“No module named ‘openpyxl’” | 缺少xlsx解析引擎 | pip install openpyxl 再重试 |
| 读取时报“No module named ‘xlrd’” | 缺xls格式解析引擎 | 如果是xlsx文件,安装openpyxl;如果是老xls,安装xlrd并注意版本 |
| 列名变成“销售额.1” | Excel里存在重名列 | 读取后用df.columns查看,重命名或只取需要的列 |
| 日期列读出来是object | 表格里混用多种日期格式 | pd.to_datetime(..., format="mixed", errors="coerce") |
| 数值列读出来是object | 带千分位逗号或货币符号 | 先astype(str)再replace再去逗号,再astype(float) |
| 所有中文都显示成方块 | matplotlib缺少中文字体配置 | 设置rcParams字体与unicode_minus |
| 数据明明有值,groupby后结果不对 | 可能是空格或不可见字符混入 | df["列"].str.strip() 清理两边空格后再分组 |
| 画图时提示“ValueError: No engines” | plot方法使用方式不对 | 检查列类型,确保是数值列;绘图前最好reset_index |
这张表的每一行都是我或者身边同事真实踩过的坑,尤其是“列名带.1”和“空格混入”这两个,极其隐蔽。你一开始看到销售额.1并不会觉得很奇怪,直到你按“销售额”取列取不到,才发现问题在哪个不经意的地方。
6.2 深挖两个最典型的坑:科学计数法与Excel进程占用
这里单独拉出两个最容易浪费时间的坑仔细讲。第一个是科学计数法问题。Excel打开一个长数字,比如手机号或订单号,会显示成“1.23E+11”,文件里存的可能还是完整数字,但pandas读取时如果没指定dtype,它可能按float64读进来,然后变成科学计数法,后面展示、匹配、导出都会出错。解决方案我在3.2提过,读取时加dtype参数,比如dtype={"手机号": str}。如果你已经读进来了,也可以:
df["手机号"] = df["手机号"].astype("Int64").astype(str)这里用了“Int64”而不是“int64”,是因为pandas的Int64类型可以保留空值,转成str后空值显示为 ,这个细节在真实数据场景很重要,直接astype(str)可能会把空值变成“nan”字符串,后面处理反而麻烦。
第二个坑是Excel进程占用。如果你用openpyxl读取了一个Excel文件,而同时这个文件还被另一个人用Office Excel打开着,读取一般没问题,但如果你用代码写入或另存,就很可能遇到PermissionError。更隐蔽的是写入后文件没被释放,Windows下提示文件被占用,你根本不知道是哪个进程。我碰到这种情况,最稳的处理是:程序里读取后不要长时间持有文件句柄,尽量一次读完立刻做下一步;如果确实需要多次读写,可以先把数据复制一份,处理副本。在命令行里可以用tasklist查看Excel进程,taskkill /F /IM EXCEL.EXE可以强制结束,但这个命令会把其他打开着的Excel也关掉,操作前记得保存其他工作。
6.3 一些提升成功率的小动作
除了上面这些报错类问题,我更想分享几个能让整个流程更顺的“小动作”。第一个是把数据文件和代码放在同一目录,用相对路径读取。我见过太多新人因为工作目录不对,用了一个看似正确的绝对路径,结果反斜杠被Python当成转义字符,报FileNotFoundError。正确写法是路径字符串前加r,即r"C:\Users\xxx\Downloads\销售表.xlsx",或者直接用正斜杠“/”。第二个是养成分步打印的习惯,每做一步数据处理就print一下形状或前几行,别等全部写完再一次性运行,不然报错了都不知道是哪一行造成的。第三个是给Excel表的每个sheet检查一下有没有“合计”“总计”这样的汇总行存在表尾,这类行在数据分析时一定要在读取阶段用skipfooter或耐心筛选掉,否则会把汇总行当成普通数据,groupby时产生一个假的“总计”分组,整张图直接画错。
再推荐一个排查小技巧:如果你发现读取结果跟你手动打开Excel看到的不一样,不用怀疑pandas有问题,先手动查看一下原表有没有隐藏列、合并单元格、筛选状态这些“看不见”的因素。Excel是个交互软件,pandas是个计算工具,两者看待表格的方式不一样,很多莫名奇妙的差异背后,往往只是原表里隐藏着你不记得的设置。
7. 写给自己和刚入坑的朋友:几条实操后的零碎心得
文章写到这儿,核心流程已经完整跑通了。最后想聊一些我在反复折腾pandas读取Excel和绘图之后沉淀下来的习惯性看法,希望对刚入坑的朋友有参考价值。
第一,永远不要相信“读到的一定是干净的”。同一个Excel文件,不同人写的,格式习惯千差万别。哪怕是同一个文件,里面有一个单元格被加了空格,或者某个日期被Excel自动转成了“####”,读取结果都会和你的预期不一样。把“读、看、改、画”四步当成默认流程,每次多花30秒看一下info和head,后面省下来的时间远远大于这30秒。我在实际工作中处理过的数据表,几乎没有一张是不需要任何清洗就直接能分析的。与其事后返工,不如把体检养成习惯。
第二,绘图的意义不只是“好看”。我第一次画出门店销售趋势图时,发现某家店的曲线在促销月份冲得特别高,但之后就一路下滑。如果只看总和,这家店全年成绩还行,看不出异常。图能帮你在最快时间内发现问题、验证猜想,这才是数据分析里最值钱的部分。pandas的plot虽然只是matplotlib的封装,但它足够让你在入门阶段把注意力放在“数据在表达什么”上,而不是先被一堆绘图API淹没。
第三,遇到问题先拆开再搜。比如你运行报错了,别直接把整段代码贴到搜索引擎里。先把错误信息里最关键的一句拆出来,比如“No module named ‘openpyxl’”,搜“read_excel openpyxl”就能精准定位。反而是那种大段上下文报错,搜出来往往对应整个项目级别的复杂问题,对新手不友好。拆解能力是这一行最基础也最重要的一项软技能,它会在你跑通第一个小项目之后,持续复利。
最后一个小技巧,写完代码记得加个注释,不要嫌麻烦。一段处理逻辑隔一周再看,你可能完全想不起当时为什么写那两行。比如“dropna(subset=[‘销售额’])”这个操作,看似简单,但如果你当时是想清掉“空白行抽样”的影响,那就值得写下来。因为实际问题往往是——当时不写,几周后换一批数据,你会把清洗逻辑误删了,然后花更多时间排查。代码注释不是写给编译器看的,是写给你自己看的。
如果这篇文章能让你在今天之内,把自己的一个Excel文件跑成一张有意义的图,那我觉得这笔时间花得很值。后面的路还很长,但第一步迈出去,剩下的路你自己就知道怎么走了。