快速上手:第一个 Pandas 程序
本教程共 54 篇 · 第 3 篇 · 更新于 2026-08-11 · 约 8 分钟阅读
本节目标:跑通第一个 pandas 程序,认识 Series 和 DataFrame,学会创建数据、查看数据和做最简单的操作。
约定俗成的导入方式
pandas 社区有个不成文的规矩:导入时用别名 pd,NumPy 用 np。后面所有章节都沿用这个写法。
import numpy as np
import pandas as pd
索引是什么
先理解一个概念:索引。pandas 里每一行数据都有一个「标签」,叫索引(index)。它像字典的键,也像表格最左边那列。
索引有点像字典的键:字典用键找值,pandas 用索引找行。区别是字典的键只能有一个,而 Series 的索引是一整列标签,可以切片、排序、参与运算。
不指定索引时,pandas 自动生成 0、1、2 这样的整数标签。也可以手动指定,让数据有语义,比如用月份当索引:
import pandas as pd
# 指定索引,数据就有了语义
s = pd.Series([120, 150, 130], index=["1月", "2月", "3月"])
print(s)
输出:
1月 120
2月 150
3月 130
dtype: int64
索引这个概念贯穿 pandas 全书,后面会反复用到。
还有一个细节:Series 打印时索引在左、数据在右;DataFrame 打印时最左边一列是行索引,顶部一行是列名。看输出时先分清哪是索引哪是数据。
创建第一个 Series
Series 是一维数据,像一列带标签的数组:
import numpy as np
import pandas as pd
# 用列表创建 Series,不传索引时自动生成 0 开头的整数索引
s = pd.Series([1, 3, 5, np.nan, 6, 8])
print(s)
输出长这样:
0 1.0
1 3.0
2 5.0
3 NaN
4 6.0
5 8.0
dtype: float64
注意 dtype 变成了 float64:数据里混进了 NaN(缺失值),整数被迫升级成浮点。
创建第一个 DataFrame
DataFrame 是二维表格,最常见的创建方式是用字典:键是列名,值是整列数据。
import pandas as pd
# 字典的键成为列名,值成为列数据
df = pd.DataFrame({
"姓名": ["张三", "李四", "王五"],
"年龄": [25, 30, 35],
"城市": ["北京", "上海", "广州"],
})
print(df)
输出:
姓名 年龄 城市
0 张三 25 北京
1 李四 30 上海
2 王五 35 广州
左边 0、1、2 是行索引,顶部是列名,这就是最典型的 pandas 表格。
查看数据
拿到表先看两眼,这几个方法最常用:
import pandas as pd
# 沿用上一节的员工表
df = pd.DataFrame({
"姓名": ["张三", "李四", "王五"],
"年龄": [25, 30, 35],
"城市": ["北京", "上海", "广州"],
})
print(df.head()) # 前 5 行,行数多时很有用
print(df.tail(2)) # 最后 2 行
print(df.shape) # 形状 (3, 3),3 行 3 列
print(df.dtypes) # 每列的数据类型
print(df.index) # 行索引
print(df.columns) # 列名
head() 默认显示 5 行,也可以传参:df.head(10) 显示前 10 行。行数很少时直接 print(df) 也行。
想看整体概况用 info():
import pandas as pd
# 沿用员工表
df = pd.DataFrame({
"姓名": ["张三", "李四", "王五"],
"年龄": [25, 30, 35],
"城市": ["北京", "上海", "广州"],
})
print(df.info())
info() 会列出每列的非空数量、类型和整体内存占用,有缺失的列一眼就能看出来。完整用法在 §17 详讲,这里先会用。
数值列想快速看统计摘要,用 describe():
import pandas as pd
df = pd.DataFrame({
"姓名": ["张三", "李四", "王五"],
"年龄": [25, 30, 35],
"城市": ["北京", "上海", "广州"],
})
print(df.describe())
它输出 count、mean、std、min、max 和四分位数,一行代码完成初步体检。每个统计量怎么读、怎么用,§18 会系统讲,这里先会用就行。
取一列,做运算
import pandas as pd
# 沿用员工表
df = pd.DataFrame({
"姓名": ["张三", "李四", "王五"],
"年龄": [25, 30, 35],
"城市": ["北京", "上海", "广州"],
})
# 取一列得到 Series
ages = df["年龄"]
print(ages.mean()) # 平均年龄 30.0
# 一次取多列(注意是双层括号)
print(df[["姓名", "年龄"]])
# 新增一列:基于已有列计算,整列一起算,不需要写循环
df["明年年龄"] = df["年龄"] + 1
print(df)
这是 pandas 最常用的套路:从表里取列,整列参与运算,结果再放回表里。多写几遍,形成肌肉记忆。
单层括号 df[“年龄”] 返回 Series,双层括号 df[[“姓名”, “年龄”]] 返回 DataFrame,区别要记牢。
修改数据
改单元格用 loc 按标签定位:
import pandas as pd
# 沿用员工表
df = pd.DataFrame({
"姓名": ["张三", "李四", "王五"],
"年龄": [25, 30, 35],
"城市": ["北京", "上海", "广州"],
})
# 修改第 0 行「年龄」列的值
df.loc[0, "年龄"] = 26
print(df)
修改会直接作用在原表上,这也是 pandas 和「函数式」风格不一样的地方,习惯就好。
loc 按标签定位;如果只知道位置,用 iloc,比如 df.iloc[0, 1] 改第 0 行第 1 列。两者区别 §19 细讲。
批量替换整列也很常见,注意列表长度必须等于行数:
import pandas as pd
# 沿用员工表
df = pd.DataFrame({
"姓名": ["张三", "李四", "王五"],
"年龄": [25, 30, 35],
"城市": ["北京", "上海", "广州"],
})
df["城市"] = ["北京", "上海", "广州"]
print(df)
筛选、排序和改名
import pandas as pd
# 沿用员工表(带明年年龄列,供改名演示)
df = pd.DataFrame({
"姓名": ["张三", "李四", "王五"],
"年龄": [25, 30, 35],
"城市": ["北京", "上海", "广州"],
"明年年龄": [26, 31, 36],
})
# 布尔筛选:留下年龄大于 28 的行
print(df[df["年龄"] > 28])
# 按年龄从大到小排序
print(df.sort_values("年龄", ascending=False))
# 给列改名
df = df.rename(columns={"明年年龄": "次年年龄"})
print(df)
df["年龄"] > 28 会得到一串 True/False,把它放进 df[...] 里,pandas 就只留下 True 对应的行。这个玩法后面会深入讲。
sort_values 默认升序,ascending=False 变降序;排序列有缺失值时,缺失行默认排在最后。
常见报错
新手最容易遇到三个报错:
- NameError: name ‘pd’ is not defined:忘了写 import pandas as pd
- KeyError: ‘年龄’:列名不存在,多半是拼写或大小写不对
- ValueError: Length of values does not match length of index:新增列的长度和表的行数不一致
看到报错先别慌,读第一行错误类型,再读最后一行具体信息,大部分问题都能定位。
第一个完整程序
把上面串起来,就是你的第一个 pandas 小程序:
import numpy as np
import pandas as pd
# 造数据:员工表和销售额
df = pd.DataFrame({
"姓名": ["张三", "李四", "王五", "赵六"],
"年龄": [25, 30, 35, 28],
"销售额": [12000, 15000, 13000, 9800],
})
# 查看概况
print(df.info())
# 平均销售额
print("平均销售额:", df["销售额"].mean())
# 找出销售额超过平均水平的员工
top = df[df["销售额"] > df["销售额"].mean()]
print(top)
运行后对比 info() 输出和 top 的内容,你能看到类型、索引、筛选结果长什么样。
程序干了四件事:造表、看结构、算平均、筛出超标的人。info() 的输出能看出表的规模和每列类型,mean() 给出整体水平,布尔筛选找出高于平均的个体——准备、体检、汇总、筛选,这是数据分析最常见的四步。跑通它,你就正式入门了。
想巩固的话,把员工表换成你手边的数据试一遍:读进来、看结构、算平均、筛异常。练习比看十遍有效。
思考题
读到这里,试着回答四个问题:
- 为什么 Series 里混入 NaN 后,dtype 会从 int64 变成 float64?
- df[“年龄”] 和 df[[“年龄”]] 返回的对象类型有什么不同?
- 布尔筛选
df[df["年龄"] > 28]里,df["年龄"] > 28本身是什么? - describe() 里的 25%、50%、75% 分别代表什么?
答不上来就回头再看一遍,这几个点后面章节都会用到。建议把答案写在纸上,学完 §05、§06 再回来对照。
记住两个概念:Series 是一维的「一列」,DataFrame 是二维的「整张表」。df[“年龄”] 取出来的是 Series。
在 Jupyter 里直接输入 df 回车,表格会渲染成漂亮的样式,比 print 更直观。交互式探索时不用写 print。