首页 / Pandas 入门教程 / 快速上手:第一个 Pandas 程序

Pandas 入门教程

快速上手:第一个 Pandas 程序

本教程共 54 篇 · 第 3 篇 · 更新于 2026-08-11 · 约 8 分钟阅读

PandasPandas 入门教程快速上手SeriesDataFrame 创建第一个程序

本节目标:跑通第一个 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() 给出整体水平,布尔筛选找出高于平均的个体——准备、体检、汇总、筛选,这是数据分析最常见的四步。跑通它,你就正式入门了。

想巩固的话,把员工表换成你手边的数据试一遍:读进来、看结构、算平均、筛异常。练习比看十遍有效。

思考题

读到这里,试着回答四个问题:

  1. 为什么 Series 里混入 NaN 后,dtype 会从 int64 变成 float64?
  2. df[“年龄”] 和 df[[“年龄”]] 返回的对象类型有什么不同?
  3. 布尔筛选 df[df["年龄"] > 28] 里,df["年龄"] > 28 本身是什么?
  4. describe() 里的 25%、50%、75% 分别代表什么?

答不上来就回头再看一遍,这几个点后面章节都会用到。建议把答案写在纸上,学完 §05、§06 再回来对照。

记住两个概念:Series 是一维的「一列」,DataFrame 是二维的「整张表」。df[“年龄”] 取出来的是 Series。

在 Jupyter 里直接输入 df 回车,表格会渲染成漂亮的样式,比 print 更直观。交互式探索时不用写 print。