拓冰建站拓冰建站
首页 / 资讯中心 / 正文

pandas入门实战:从Series、DataFrame到数据处理全流程

如果你问我做数据分析、跑机器学习预处理甚至只是平时处理 Excel 表格太卡、太费手最值得花时间学的一个 Python 库是什么我大概率会先说 pandas。pandas 是 Python 数据处理领域绕不开的存在。它提供了一套类似 Excel 但又远比 Excel 灵活的数据结构能让你用代码快速完成数据读取、清洗、筛选、分组、统计、合并、时间序列处理等操作。凡是和数据打交道的人无论是数据分析师、算法工程师、运维还是学生党做课程设计都会在某个时刻和 pandas 撞个满怀。这篇 pandas 入门文章我会从安装开始把 Series、DataFrame、切片索引、数据类型转换、缺失值处理这些核心基础过一遍再把实际使用中容易踩的坑和排查思路整理出来最后用一份鸢尾花数据集完整演示一遍数据处理流程让你不仅能看懂还能直接照着操作。适合谁来读写过一点 Python、知道列表和字典是什么但还没有系统学过 pandas 的人。如果你之前只是零零散散抄过几段代码不知道为什么要这么写这篇文章会帮你把这些碎片串起来。1. pandas 到底在解决什么问题1.1 数据形态的转变在没有 pandas 之前我们要用 Python 处理表格数据通常只能靠嵌套列表或者字典列表硬扛。比如一个班级成绩表用列表存大概是这样的grades [ [张三, 数学, 85], [张三, 语文, 92], [李四, 数学, 78], ]这种结构存起来没问题但一旦要做条件筛选、按列求和、按姓名分组汇总代码写起来就会非常吃力。你得自己写循环遍历每一行还要手动维护列名和列索引的对应关系。数据量小还能忍上万行数据之后就完全是灾难。pandas 做的第一件事就是把“数据”和“操作数据的语义”绑定起来。它把表格抽象成 DataFrame——每一列有列名每一行有行索引你可以用列名直接取数据可以用类似 SQL 的思维做筛选和分组甚至可以直接对接 Excel、CSV、数据库。和 Excel 相比pandas 的最大优势是所有操作都可以脚本化、自动化、可复现。你改一个参数重跑一遍脚本整个数据处理流程就更新完了不用像在 Excel 里那样手工重复操作。1.2 pandas、NumPy 和 Matplotlib 的关系很多刚接触 pandas 的人会被它和 NumPy、Matplotlib、scikit-learn 之间的关系搞糊涂。我打个比方NumPy 是底层数组地基pandas 是建在它上面的“精装房”有自己的房间编号索引和门牌标签列名住起来舒服Matplotlib 是装修工具负责把房子里的样子画出来而 scikit-learn 是把房子变成“可出租的商用空间”专门做机器学习建模。实际做数据分析时pandas 负责数据整理NumPy 负责数值计算Matplotlib 负责可视化最后送进 scikit-learn 跑模型这是一条非常标准的数据流水线。这篇文章虽然以 pandas 为主但到后面的实战环节也会稍微演示它们如何配合。1.3 什么场景下适合用 pandas我自己判断一个场景要不要引入 pandas通常就看三条数据是不是二维表结构有行有列要不要做条件筛选、分组、聚合这类操作数据源头是不是 CSV、Excel、SQL 这类常见格式。只要中了两条直接用 pandas 基本不会错。像接个小 API 返回 JSON转成 DataFrame 再处理也很快。只有一种情况我建议放弃 pandas那就是数据量大到单机内存完全装不下且查询逻辑非常简单——这时候应该考虑数据库或分布式工具。但那是后话pandas 入门阶段可以暂时不考虑性能瓶颈。2. 搭好环境装对版本2.1 PyCharm 安装 pandas 的两种方式搜索热词里有人问“pycharm 怎么安装 pandas 包”这确实是新手卡得最多的一步。其实说白了安装第三方库就是让 Python 环境里多一份 pandas 的可用文件途径无非命令行和 IDE 图形界面两种。第一种是命令行。在 PyCharm 底部自带的 Terminal 里或者在你自己的终端里确认当前用的是哪个 Python 环境后运行pip install pandas如果网络比较慢或者一直提示超时可以加国内镜像源。国内速度快一点的方案pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple第二种是图形界面。打开 PyCharm进入 File - Settings - Project - Python Interpreter点右上角加号搜索 pandas选中后点击 Install Package。这个方式的好处是可以直观看到安装进度适合不习惯命令行的人。但核心逻辑还是一样的把 pandas 装到你当前项目所绑定的 Python 解释器里。最常见的报错是ModuleNotFoundError: No module named pandas翻译过来就是当前解释器里没有 pandas。多数情况是你终端里用哪个 Python 装的包和 PyCharm 里选的解释器不是同一个只要在 PyCharm 里重新安装一遍就能解决。2.2 pip 安装背后的版本选择有人问要不要指定版本。我的建议是入门阶段直接装最新稳定版就行不用特别指定版本号。pandas 的 API 兼容性做得还不错常见操作在新版本里基本不会大改。但如果你是要跑一个老项目别人用的是 1.3.x你直接装 2.x 就可能遇到某些函数的行为差异。稳妥的做法是先看项目里有没有requirements.txt或environment.yml有就按文件里的版本装。安装完成后可以用下面这段代码检查版本import pandas as pd print(pd.__version__)pd是 pandas 事实上的标准别名。你几乎不会看到有人写import pandas后全程用pandas.xxx()大家都约定俗成地写成pd这也是你以后看别人代码最常见的样子。养成这个习惯和社区代码保持一致能省很多麻烦。2.3 多环境管理更省心如果你装了 Anaconda创建独立虚拟环境比直接在 base 环境里塞包更干净。比如conda create -n data python3.10 conda activate data pip install pandas这样你之后装一个很重的库把环境搞坏了直接删掉这个环境重新来就行不会影响到系统 Python 或者其他项目。PyCharm 里也能配置新环境Settings - Project - Python Interpreter - Add Interpreter - Conda Environment选择 Existing environment 或者新建一个都行。3. 两个核心数据结构先吃透它们3.1 Series带标签的一维数组pandas 里有两种最基本的数据结构Series 和 DataFrame。Series 可以看成是“带标签的一维数组”它既像 Python 字典又像一列 Excel 数据。最简单的创建方式import pandas as pd s pd.Series([10, 20, 30], index[a, b, c]) print(s)输出长这样a 10 b 20 c 30 dtype: int64左边是索引index右边是值values。索引不一定要从 0 开始你可以给每一行赋予有意义的标签。取数据的时候既可以用位置也可以用标签print(s[0]) # 10按位置取 print(s[a]) # 10按标签取有人会觉得这和多维数组没太大区别但 Series 真正有用的地方在于索引本身可以参与运算对齐。比如两个 Series 做加法pandas 会按索引自动对齐而不是机械地按下标相加。这个特性在数据处理时非常实用但也经常让新手一脸懵后面我专门讲一部分。3.2 DataFrame带行列标签的二维表DataFrame 是 pandas 里最常用的主数据结构。它就像一张 Excel 表格每一列是一个 Series多个 Series 共用一个行索引就拼成了 DataFrame。创建 DataFrame 的方式很多我用字典最顺手import pandas as pd df pd.DataFrame({ name: [Alice, Bob, Cathy], age: [25, 32, 28], city: [北京, 上海, 广州], }) print(df)输出name age city 0 Alice 25 北京 1 Bob 32 上海 2 Cathy 28 广州列名就是字典的键行索引默认从 0 开始。你还可以自己指定行索引df pd.DataFrame(data, index[row1, row2, row3])这里有个细节值得注意pandas 会尽力推断每列的数据类型。上面例子里age被推断成int64字符串列会被推断成object。推断规则通常是按列整体看如果某一列混入了数字和字符串整列可能直接变成object。这个推断机制是后来很多“类型不对”问题的根源。3.3 索引到底是怎么回事索引index是 pandas 区别于普通二维数组的核心。你可以把它理解成表格左侧那列行号只不过它不一定是数字也可以是时间、字符串甚至多级索引。刚开始学不用太纠结多级索引但要记住三个概念index行索引df.index可以查看columns列索引也就是列名df.columns可以查看values真正存储数据的那块二维数组df.values返回 NumPy 数组。很多教程一上来就大谈索引对齐新手容易迷失。我的建议是先记住“一行一列都要能找到名字”能做到这一点后面学loc、iloc就有了基础。等到你真正遇到两个 DataFrame 合并后结果出现 NaN再回头理解索引对齐就水到渠成了。下面这张表可以帮你快速对照属性作用返回类型df.index查看行索引Indexdf.columns查看列名Indexdf.values查看底层数据NumPy ndarraydf.dtypes查看每列数据类型Seriesdf.shape查看形状行数、列数tuple4. 从读取数据到基本操作边用边学最快4.1 用 Read 函数把文件读进来pandas 入门阶段最常用的功能就是读写文件。读 CSV 用pd.read_csv()读 Excel 用pd.read_excel()读 SQL 用pd.read_sql()。这里我先讲 CSV因为它最常见而且坑也最多。df pd.read_csv(data.csv)读进来的df就是一个 DataFrame。如果你只需要前几行看看长什么样用df.head()想看看每列的数据类型和非空值统计用df.info()想看得数值型列的分布用df.describe()。这三句话我几乎每次拿到新数据都会先跑一遍相当于给数据做个“体检”。关于文件路径最常见的问题是明明文件在项目文件夹里还是报FileNotFoundError。原因多半是当前工作目录和文件实际位置不一致。稳妥的办法是用绝对路径或者在 PyCharm 里右键数据文件选择 Copy Path粘贴到代码里。如果是学生党在实训平台上做作业通常平台会要求你把数据文件放在指定目录或者直接调用内置的数据加载函数看清题目要求就行。4.2 切片和索引行列定位的两种逻辑pandas 的切片索引是新手最搞不清的地方热搜词里“pandas 基本操作切片索引”一直热度不减原因就在这里。其实 pandas 给了你两套工具按标签取用loc按位置取用iloc。# 按行索引标签取 df.loc[0] # 取第一行标签为0的那行 df.loc[0, name] # 取第一行 name 列 # 按位置取 df.iloc[0] # 取第一行 df.iloc[0, 1] # 取第一行第二列 df.iloc[:, 0] # 取第一列所有行这里最容易翻车的地方在于df[0:2]虽然看似取前两行但它用的是 Python 切片语法左闭右开而且只对行生效。如果你想按列筛选基本操作是df[name] # 取单列返回 Series df[[name, age]] # 取多列返回 DataFrame列筛选用方括号 列名行筛选更推荐用loc/iloc。这样代码读起来语义明确不容易踩坑。还有一种使用频率极高的筛选方式是布尔索引。例如筛选年龄大于 30 的人df[df[age] 30]不要觉得这个语法奇怪它背后是先算出df[age] 30这个布尔 Series再用它去索引原表。执行顺序是先比较再筛选。这也是 pandas 筛选数据最灵活、最强大的一种方式。4.3 数据类型转换本质是“告诉 pandas 你想要的类型”数据处理中经常遇到类型不匹配的问题。例如你从 CSV 读进来一个2024-01-15它默认是字符串你读进来一个12345它可能是字符串而不是整数。这时候就要显式转换类型。pandas 里最通用的转换方法就是astype()df[age] df[age].astype(int) df[date] pd.to_datetime(df[date])astype()适合数值、字符串之间的转换。日期列一般不用astype而是用pd.to_datetime()因为它能识别多种日期格式并统一转成 pandas 的时间类型。数据类型转换中最常见的坑是这样的某列看起来全是数字但astype(int)却报错。原因多半是列里藏着看不见的“脏数据”比如空格、换行符、逗号分隔符或者是真正的字符串“N/A”。解决办法是先用字符串方法清洗df[price] df[price].str.replace(,, ).str.strip() df[price] pd.to_numeric(df[price], errorscoerce)这里errorscoerce的意思是把无法转换的非法值变成缺失值NaN而不是直接让程序崩溃。这个参数很有用能让类型转换在脏数据场景下安全继续。4.4 缺失值处理pd.NA、NaN 和 dropna 双剑合璧缺失值是数据分析里躲不掉的课题。pandas 里表示缺失值常见的有NaN来自 NumPy和pd.NApandas 引入的可空类型。大多数情况下你不需要刻意区分它们只要知道df.isna()或df.isnull()能判断缺失值就行。处理缺失值策略一般分两种删除和填充。# 删除含缺失值的行 df_clean df.dropna() # 填充缺失值 df_filled df.fillna(0) df_filled df.fillna(df[age].mean())dropna()默认删除“只要有一个缺失值就删掉整行”。有些场景你只想删除某列缺失的行需要传subset参数df.dropna(subset[name])这个细节很容易被忽略但很实用。比如你想按“姓名”关联数据姓名缺失的行干脆就没必要留了而其他列有缺失还能继续分析。填充缺失值时用均值、中位数填充数值列是常见的做法。不过要注意如果列是分类变量用众数填充更合理如果是时间序列用前向填充methodffill也很常用。5. 常见报错与实战排查技巧5.1 KeyError 和索引越界先分清你是按什么取的新手最常撞见的一个报错就是KeyError: xxx。这句话的意思通常是你想用名字去取一个不存在的列或索引。比如df[weight] # weight 这列根本不存在解决办法也很简单先打印df.columns看看正确的列名到底是什么。我见过太多人因为df.columns里有个看不见的空格导致 KeyError 反复出现。如果用的是iloc取行遇到IndexError: single positional indexer is out-of-bounds那说明你要的位置超出了实际行数。注意iloc和loc的报错完全不一样前者按位置取越界报 IndexError后者按标签取没这个标签报 KeyError。这个区分能帮你快速定位问题出在哪一步。5.2 用 assert 检查数据把错误拦在源头在数据处理脚本里assert很适合做数据质量校验。比如你要求处理后的表必须有 10 列、没有重复列名、某列不存在缺失值可以直接写assert df.shape[1] 10, 列数不对 assert df[id].notna().all(), id 列存在缺失值 assert df[age].between(0, 120).all(), 存在非法年龄如果条件不满足程序会直接抛出异常把问题暴露在早期而不是让坏数据一路跑到最后才爆雷。另外pandas 的测试模块里还提供了pandas.testing.assert_frame_equal可以用来比较两个 DataFrame 是否完全相等from pandas.testing import assert_frame_equal assert_frame_equal(df1, df2)这个主要用于单元测试场景比如你写了一个数据清洗函数可以用它验证函数的输出是否符合预期。比较时会检查列名、索引、数据类型、值内容比手动写循环比较高效得多。5.3 时间序列处理先转成 datetime 再操作热搜词里还提到“时间序列处理”这也是 pandas 一个非常强势的领域。处理时间序列的第一步永远是先把时间列转成datetime类型df[date] pd.to_datetime(df[date])转成时间类型之后你才能使用.dt访问器提取年、月、日、星期等信息df[year] df[date].dt.year df[weekday] df[date].dt.dayofweek如果要把时间列设为行索引以便做重采样之类的时间序列分析可以df df.set_index(date) df.resample(M).mean() # 按月聚合时间序列处理常见的坑是时间格式不统一。比如有的行是2024/01/01有的行是2024-01-01pd.to_datetime一般能自动解析但如果出现2024年1月1日这种格式还是得先手动规范化。5.4 数据量大时的小优化pandas 在数据量几千万行以上时容易变慢但入门阶段更常遇到的问题是“代码写法太低效”。比如循环逐行更新 DataFrame 是一种性能灾难更推荐用向量化操作# 不推荐 for i in range(len(df)): df.loc[i, new_col] df.loc[i, col] * 2 # 推荐 df[new_col] df[col] * 2pandas 内部基于 NumPy 做了大量优化尽量用整列计算避免 Python 级别的循环。还有一个常用技巧当你只取一列做判断时用df[country].value_counts()可以快速统计分组频数比手动groupby再count更省事。6. 用 iris 数据集完整跑一遍流程6.1 加载数据了解数据结构鸢尾花数据集iris是机器学习里最经典的示例数据之一非常适合演示 pandas 基本操作。你可以直接用 scikit-learn 提供的数据也可以从本地或在线资源读取 CSV 版本。先用 pandas 载入并做“体检”import pandas as pd from sklearn.datasets import load_iris iris load_iris() df pd.DataFrame(iris.data, columnsiris.feature_names) df[species] iris.target df[species] df[species].map({0: setosa, 1: versicolor, 2: virginica}) print(df.head()) print(df.info()) print(df.describe())head()看前五行确认数据结构对不对info()看各列是否有缺失值、类型是否正确describe()看数值列的均值、标准差、最小值、最大值能快速发现量纲差异。三行代码走下来这个数据集长什么样基本就有数了。6.2 筛选分组找出规律接下来做几个基本操作。比如只看 versicolor 品种的数据versi df[df[species] versicolor]按品种分组统计平均花萼长度df.groupby(species)[sepal length (cm)].mean()想同时看多个列的统计量可以用agg()df.groupby(species).agg( sepal_mean(sepal length (cm), mean), petal_max(petal length (cm), max), )这一步能直观看出不同品种之间存在明显差异也给后续建模提供了很好的特征依据。我自己用 pandas 做这一类分析时特别喜欢把groupby和agg组合起来一次算完既清晰又高效。6.3 数据可视化与建模的前置准备pandas 本身不带特别强大的绘图功能但它内置的plot方法默认调用 Matplotlib非常适合快速画图。导入方式是import matplotlib.pyplot as plt df.groupby(species)[sepal length (cm)].mean().plot(kindbar) plt.show()如果想把数据送进 scikit-learn 建模pandas 和 sklearn 的配合也基本是无缝的。准备好特征矩阵X和目标向量yX df[iris.feature_names] y df[species] from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 )可以看到pandas 在前半段负责把数据整理成规整的二维表sklearn 在后半段直接吃这份表。所以“pandas numpy matplotlib scikit-learn”这条工具链本质上是同一个工作流里各司其职的四个环节。6.4 导出结果收尾勿忘分析完数据如果想把清洗后的结果保存下来pandas 提供了很便捷的导出功能df.to_csv(iris_clean.csv, indexFalse) df.to_excel(iris_clean.xlsx, indexFalse)导出 CSV 时记得加上indexFalse否则默认会把行索引也写进文件多出一列无用数据。遇到 Excel 导出报错时大多数情况是缺少openpyxl库装上就行pip install openpyxl最后分享一个我自己常用的习惯每个数据处理脚本开头先写一行注释说明这份数据来自哪里、要做什么每次读入数据后立刻跑df.info()和df.head()每次导出结果前再跑一次assert检查关键字段是否完整。这些习惯看起来不起眼但能帮你避免大量“数据文件到底在哪里”“结果为什么少了几行”这类让人头大的问题。pandas 入门并不需要把所有函数都背下来先掌握文件读取、loc/iloc切片、布尔筛选、groupby分组、astype类型转换、缺失值处理这六板斧就已经能覆盖日常 80% 以上的数据处理需求。剩下的函数等你遇到具体问题再查文档或者直接在搜索引擎里搜“pandas 怎么做某某操作”基本都能找到答案。这也是我这么多年用下来的真实体会pandas 不是一门记忆型学问而是一门操作型技能用多了手感自然就有了。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门