笔记 / Pandas · 更新于 2026-10-15

Pandas


1. 环境与安装

# pip 安装(使用清华镜像)
pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple

# conda 安装
conda install pandas

2. Series(一维带标签数组)

创建方式

import pandas as pd
import numpy as np

# 从列表(默认索引 0,1,2...)
pd.Series([11, 22, 33])

# 自定义索引
pd.Series([10, 20], index=["手机", "电脑"], name="销量")

# 从字典(键→索引,值→数据)
pd.Series({"北京": 200, "上海": 300})

# 字典 + 指定 index(自动对齐,缺失填 NaN)
pd.Series({"北京": 200, "上海": 300}, index=["北京", "广州"])  # 广州→NaN

# 从 NumPy 数组
pd.Series(np.random.randint(1,100,5), index=["a","b","c","d","e"])

# 空 Series(后续赋值)
s = pd.Series(dtype=int)
s["语文"] = 95

核心属性(不加括号)

属性 说明
s.index 行标签
s.values 底层 NumPy 数组
s.ndim 维度(恒为 1)
s.shape 形状元组 (n,)
s.size 元素个数
s.dtype 数据类型
s.name 列/系列名称

3. 索引访问(四驾马车)

访问器 带 i? 基于 切片规则 适用场景
s.loc[] ❌ 标签名 首尾双闭 批量/切片
s.iloc[] ✅ 数字位置 左闭右开 传统数字切片
s.at[] ❌ 标签名 不支持切片 单个元素(极快)
s.iat[] ✅ 数字位置 不支持切片 单个元素(极快)
s = pd.Series([10,20,30,40], index=["a","b","c","d"])
s.loc["a":"c"]   # → a,b,c(包含 c)
s.iloc[0:3]      # → a,b,c(不含位置3)
s.at["b"]        # → 20
s.iat[1]         # → 20

4. 运算与布尔筛选

广播运算(无需 for 循环)

s = pd.Series([1000,2000,3000], index=["张三","李四","王五"])
s + 500          # 全体加薪
s * 1.1          # 全体涨10%

布尔筛选(两步法)

s = pd.Series([10,20,30,40], index=["a","b","c","d"])
mask = s > s.mean()   # 生成 True/False
s[mask]               # 筛选出 >25 的值

⚠️ 多条件必须加括号,且用 & / |

# 正确
s[(s > 15) & (s < 35)]
# 错误:s[s > 15 & s < 35] 或 s[s > 15 and s < 35]

5. 缺失值处理(NaN)

s = pd.Series([10, np.nan, 20, np.nan, 30])

s.isna()              # 判断是否缺失
s.dropna()            # 删除缺失行
s.fillna(s.mean())    # 用均值填充

6. 探索性统计与去重

s_items = pd.Series(["苹果","苹果","香蕉","香蕉","橙子"])

s_items.value_counts()        # 频数统计(降序)
s_items.drop_duplicates()     # 去重保留第一个
s_items.unique()              # 去重后的 NumPy 数组
s_items.nunique()             # 唯一值个数

7. 时间序列常用操作

# 生成日期序列
pd.date_range(start="2026-03-01", periods=5, freq="B")  # 工作日

# 频率别名: D(日), B(工作日), W(周), MS(月初), ME(月末), h(小时)

# 重采样(时间维度聚合)
sales.resample("W").sum()     # 按周求和

# 差分与环比
temp.diff()                   # 当天 - 前一天
temp.pct_change()             # 环比变化率

8. DataFrame(二维表格)

创建方式

# 从字典(键→列名,值→等长列表)
pd.DataFrame({"姓名": ["张三","李四"], "年龄": [20,25]})

# 从二维列表(需指定 columns)
pd.DataFrame([["张三",20],["李四",25]], columns=["姓名","年龄"])

# 从 NumPy 矩阵
pd.DataFrame(np.random.randint(60,100,(5,3)), columns=["数学","语文","英语"])

# 从 Series 字典(自动索引对齐)
s1 = pd.Series([90,80], index=["张三","李四"])
s2 = pd.Series([85,95], index=["李四","王五"])
pd.DataFrame({"数学": s1, "英语": s2})   # 自动对齐,缺失填 NaN

# 空表动态追加
df_empty = pd.DataFrame(columns=["姓名","得分"])
df_empty.loc[0] = ["张三", 100]

快速概览

df.info()      # 列类型、非空数、内存
df.describe()  # 数值列的统计描述

9. DataFrame 列操作(增/改/删/分箱)

# 增
df["总分"] = df["数学"] + df["英语"]

# 改(分箱)
bins = [0, 60, 85, 100]
labels = ["不及格", "良好", "优秀"]
df["等级"] = pd.cut(df["数学"], bins=bins, labels=labels)

# 删
df.drop(columns=["数学","英语"], inplace=True)   # axis=1 列

10. DataFrame 行操作(筛选/删除/遍历)

# loc 行+列切片(双闭)
df.loc["a":"b", ["姓名","城市"]]

# 条件筛选
df[df["年龄"] > 22]

# 逐行遍历(配合 at 快速修改)
for idx, row in df.iterrows():
    df.at[idx, "新列"] = row["年龄"] * 2   # 高效修改单个值

11. 缺失值/重复值清洗(DataFrame)

df.isna().sum()                       # 各列缺失计数
df.dropna(axis=0, how="all")          # 删除全空行
df.dropna(subset=["订单号","金额"], how="any")  # 指定列有缺失则删
df.drop_duplicates(keep="first")      # 去重(保留第一个)

12. 分组聚合(groupby + agg)

# 单列聚合
df.groupby("品类")["销量"].sum()

# 多列多指标(agg 字典)
df.groupby("品类").agg({
    "销量": ["max", "mean"],
    "销售额": "sum"
})

13. 表拼接与合并

concat(上下堆叠,结构相同)

pd.concat([df1, df2], axis=0)   # axis=0 行方向

merge(主键关联,类似 VLOOKUP)

pd.merge(df_info, df_score, on="学号", how="left")   # left, inner, outer, right

14. 文件读写(CSV / Excel / SQLite)

CSV

# 写入(防中文乱码)
df.to_csv("out.csv", encoding="utf-8-sig", index=False)

# 读取(指定编码、只选部分列)
pd.read_csv("in.csv", encoding="gbk", usecols=["学号","姓名"])

Excel

df.to_excel("out.xlsx", sheet_name="期末考", index=False)
pd.read_excel("in.xlsx", sheet_name="期末考")

SQLite(内置,免配置)

from sqlalchemy import create_engine
engine = create_engine("sqlite:///mydb.db")
df.to_sql("table_name", con=engine, if_exists="replace", index=False)
pd.read_sql("SELECT * FROM table_name WHERE 语文 > 85", con=engine)

15. 数据透视表(pivot_table)

pd.pivot_table(df,
               index="地区",          # 行
               columns="产品",        # 列
               values="销售额",       # 聚合值
               aggfunc="sum",         # 聚合函数
               fill_value=0,          # 缺失填充
               margins=True)          # 显示总计

16. 快速绘图(Matplotlib)

import matplotlib.pyplot as plt

# 解决中文乱码
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 假设 summary 为 Series
summary.plot(kind="bar", color="#ff6666", figsize=(8,5))
plt.title("标题")
plt.xlabel("X轴")
plt.ylabel("Y轴")
plt.grid(axis='y', alpha=0.3)
plt.show()

17. 常见报错速解

报错 原因 解决
UnicodeDecodeError 文件编码不是 utf-8 read_csv(encoding="gbk")
KeyError: 'xxx' 列名不存在/拼写错误 先 print(df.columns) 核对
ValueError: ... and 多条件用了 and / 漏括号 用 &,每个条件加括号
SettingWithCopyWarning 对切片子表直接赋值 切片时加 .copy()
ModuleNotFoundError: openpyxl 未安装 Excel 读写引擎 pip install openpyxl