news 2026/9/18 13:53:34

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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.txtenvironment.yml,有就按文件里的版本装。

安装完成后可以用下面这段代码检查版本:

import pandas as pd print(pd.__version__)

pd是 pandas 事实上的标准别名。你几乎不会看到有人写import pandas后全程用pandas.xxx(),大家都约定俗成地写成pd,这也是你以后看别人代码最常见的样子。养成这个习惯,和社区代码保持一致,能省很多麻烦。

2.3 多环境管理更省心

如果你装了 Anaconda,创建独立虚拟环境比直接在 base 环境里塞包更干净。比如:

conda create -n data python=3.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 数组。

很多教程一上来就大谈索引对齐,新手容易迷失。我的建议是:先记住“一行一列都要能找到名字”,能做到这一点,后面学lociloc就有了基础。等到你真正遇到两个 DataFrame 合并后结果出现 NaN,再回头理解索引对齐,就水到渠成了。

下面这张表可以帮你快速对照:

属性作用返回类型
df.index查看行索引Index
df.columns查看列名Index
df.values查看底层数据NumPy ndarray
df.dtypes查看每列数据类型Series
df.shape查看形状(行数、列数)tuple

4. 从读取数据到基本操作,边用边学最快

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"], errors="coerce")

这里errors="coerce"的意思是把无法转换的非法值变成缺失值NaN,而不是直接让程序崩溃。这个参数很有用,能让类型转换在脏数据场景下安全继续。

4.4 缺失值处理:pd.NA、NaN 和 dropna 双剑合璧

缺失值是数据分析里躲不掉的课题。pandas 里表示缺失值常见的有NaN(来自 NumPy)和pd.NA(pandas 引入的可空类型)。大多数情况下你不需要刻意区分它们,只要知道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"])

这个细节很容易被忽略,但很实用。比如你想按“姓名”关联数据,姓名缺失的行干脆就没必要留了,而其他列有缺失还能继续分析。填充缺失值时,用均值、中位数填充数值列,是常见的做法。不过要注意:如果列是分类变量,用众数填充更合理;如果是时间序列,用前向填充(method="ffill")也很常用。

5. 常见报错与实战排查技巧

5.1 KeyError 和索引越界,先分清你是按什么取的

新手最常撞见的一个报错就是KeyError: 'xxx'。这句话的意思通常是:你想用名字去取一个不存在的列或索引。比如:

df["weight"] # weight 这列根本不存在

解决办法也很简单:先打印df.columns,看看正确的列名到底是什么。我见过太多人因为df.columns里有个看不见的空格,导致 KeyError 反复出现。

如果用的是iloc取行,遇到IndexError: single positional indexer is out-of-bounds,那说明你要的位置超出了实际行数。注意ilocloc的报错完全不一样,前者按位置取,越界报 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"] * 2

pandas 内部基于 NumPy 做了大量优化,尽量用整列计算,避免 Python 级别的循环。还有一个常用技巧:当你只取一列做判断时,用df["country"].value_counts()可以快速统计分组频数,比手动groupbycount更省事。

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, columns=iris.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 做这一类分析时,特别喜欢把groupbyagg组合起来一次算完,既清晰又高效。

6.3 数据可视化与建模的前置准备

pandas 本身不带特别强大的绘图功能,但它内置的plot方法默认调用 Matplotlib,非常适合快速画图。导入方式是:

import matplotlib.pyplot as plt df.groupby("species")["sepal length (cm)"].mean().plot(kind="bar") plt.show()

如果想把数据送进 scikit-learn 建模,pandas 和 sklearn 的配合也基本是无缝的。准备好特征矩阵X和目标向量y

X = 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_size=0.2, random_state=42 )

可以看到,pandas 在前半段负责把数据整理成规整的二维表,sklearn 在后半段直接吃这份表。所以“pandas + numpy + matplotlib + scikit-learn”这条工具链,本质上是同一个工作流里各司其职的四个环节。

6.4 导出结果,收尾勿忘

分析完数据,如果想把清洗后的结果保存下来,pandas 提供了很便捷的导出功能:

df.to_csv("iris_clean.csv", index=False) df.to_excel("iris_clean.xlsx", index=False)

导出 CSV 时记得加上index=False,否则默认会把行索引也写进文件,多出一列无用数据。遇到 Excel 导出报错时,大多数情况是缺少openpyxl库,装上就行:

pip install openpyxl

最后分享一个我自己常用的习惯:每个数据处理脚本开头,先写一行注释说明这份数据来自哪里、要做什么;每次读入数据后,立刻跑df.info()df.head();每次导出结果前,再跑一次assert检查关键字段是否完整。这些习惯看起来不起眼,但能帮你避免大量“数据文件到底在哪里”“结果为什么少了几行”这类让人头大的问题。

pandas 入门并不需要把所有函数都背下来,先掌握文件读取、loc/iloc切片、布尔筛选、groupby分组、astype类型转换、缺失值处理这六板斧,就已经能覆盖日常 80% 以上的数据处理需求。剩下的函数,等你遇到具体问题再查文档,或者直接在搜索引擎里搜“pandas 怎么做某某操作”,基本都能找到答案。这也是我这么多年用下来的真实体会:pandas 不是一门记忆型学问,而是一门操作型技能,用多了,手感自然就有了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 13:53:00

家谱管理系统核心实现:C语言树结构选型与遍历算法解析

简介:基于数据结构的家谱管理系统课程设计文档,面向计算机相关专业学生,用于完成数据结构大作业或课程综合设计。资源内包含家谱系统完整实现方案,以双链二叉树存储成员信息,涵盖姓名、出生日期、婚否、地址、健在状态…

作者头像 李华
网站建设 2026/9/18 13:50:58

如何配置livox_ros_driver2的HAP盲区:blind_spot_set 50-200cm详解

如何配置livox_ros_driver2的HAP盲区:blind_spot_set 50-200cm详解 【免费下载链接】livox_ros_driver2 Livox device driver under Ros(Compatible with ros and ros2), support Lidar HAP and Mid-360. 项目地址: https://gitcode.com/GitHub_Trending/li/livox…

作者头像 李华
网站建设 2026/9/18 13:50:27

CD4011红外防盗报警器:纯硬件RS锁存器设计与抗干扰实战

简介:本资源是一份面向电子类本科生及电子爱好者的基础实践型毕业设计文档,聚焦家庭安防场景下的红外防盗报警器硬件实现,解决传统单一住宅报警系统缺乏扩展性与逻辑判断能力的问题。文档以CD4011四路NAND门芯片为核心构建逻辑处理电路&#…

作者头像 李华
网站建设 2026/9/18 13:48:08

智慧校园智能网络广播系统全解析:从部署到运维的实战经验

做智慧校园项目的这几年,我越来越觉得,智能网络广播系统是学校里最没存在感、但又最不能出问题的系统。平时没人会注意到天花板上那几个音箱,可一旦英语听力考试、运动会通知、宿舍紧急集合或者消防疏散的时候掉链子,全校师生都会…

作者头像 李华
网站建设 2026/9/18 13:47:10

AI Agent 跑 Harness 监控告警:模型认证走 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华