LLM系列:1.python入门:14.Pandas
Pandas
一.认识Pandas
==Pandas 是建立在 NumPy 基础之上的面板数据(Panel Data)和数据分析(Data Analysis)通用工具包。==相比于 NumPy 提供了较为基础的数组结构数据,Pandas 则提供了主要面向表格数据分析处理的灵活数据结构和工具。二维表格数据是数据分析和机器学习场景下最常用的数据结构。
导入 Pandas 时,通常给其一个别名"pd",并且由于其基于 NumPy,通常需要同时导入两者:
import numpy as np
import pandas as pd
二.Pandas对象类型简介
Pandas核心定义了三类对象,分别是Series、Index和DataFrame。
- Series和Numpy中array非常类似,相当于是array的改进版,其中最重要的区别就是Series能够提供显示索引,从而为表结构的行标和列标提供了基础;
- Index是一种特殊的序列,可以看成是一种显示索引的集合;
- DataFrame是二维表结构数据的直接表示,由多个Series共同构成的数据结构,也是实际使用Pandas过程中最常用的数据结构。
三.Series
Series是一维的、带标签的数组,可以看作是一个带有灵活索引(Index)的一维NumPy数组;即:Series = Index + 一维ndarry。 np.xxx()函数,大多数都可以直接接受Pandas的Series作为参数(自动转成ndarry)!
0. Series属性
Series 对象最核心的四个属性(调用时不加括号):
values:返回Series内部存储的实际数据(ndarray)。index:返回Series的索引对象(Index)。dtype:返回Series内部元素的数据类型对象(dtype)。name:返回Series的名称(字符串,常在转化为DataFrame时作为列名)。
其他属性补充(基本与 NumPy 数组和 DataFrame 的部分属性保持一致):
1. 形状与大小 (Shape & Size)
size:返回 Series 中元素的总个数(整数)。shape:返回 Series 的形状,格式为元组(例如(n,))。ndim:返回 Series 的维度数(整数,Series 始终是一维的,返回1)。2. 数据状态检测 (Data Status)
empty:判断 Series 是否为空(返回布尔值True或False)。hasnans:判断 Series 中是否包含缺失值 NaN(返回布尔值True或False)。is_unique:判断 Series 中的所有元素是否完全不重复(返回布尔值True或False)。is_monotonic_increasing:判断 Series 的数据是否单调递增。is_monotonic_decreasing:判断 Series 的数据是否单调递减。
1. Series - 创建一维数据对象
作用:将列表、数组、字典或标量转换为Pandas的Series对象。
pd.Series(data=None, index=None, dtype=None, name=None)
参数:
-
数据 (data): 需要转换为 Series 的输入数据,可以是列表、NumPy 数组、字典或单一标量(array-like/dict/scalar)。
注:1. 如果data是字典类型,字典的键自动变成索引;2. scalar是标量的意思,不是某一个特定类的名字,指单元且不可再分的基本数值,
-
索引 (index): 可选参数,手动指定数据的行标签序列。如果不指定,默认生成从0开始的整数索引(array-like/Index)。
-
数据类型 (dtype): 可选参数,强制指定数据类型(dtype)。
-
名称 (name): 可选参数,为该 Series 对象命名(str)。
返回值:
- 成功: 返回一个带有标签的一维 Series 对象(Series)。
示例:
# 1. 由列表/数组创建(默认索引)
s1 = pd.Series([0.25, 0.5, 0.75, 1.0])
# 0 0.25
# 1 0.50
# 2 0.75
# 3 1.00
# dtype: float64
# 2. 由标量创建(必须提供索引,标量会广播填充)
s2 = pd.Series(5, index=[100, 200, 300])
# 100 5
# 200 5
# 300 5
# dtype: int64
# 3. 由字典创建(字典的键自动变成索引)
population_dict = {'California': 3833, 'Texas': 1966, 'New York': 1965}
s3 = pd.Series(population_dict)
# California 3833
# Texas 1966
# New York 1965
# dtype: int64
# 4. 前三种形式都可以通过显式指定索引筛选需要的结果
pd.Series({2:'a', 1:'b', 3:'c'}, index=[3, 2]) #只会保留index是3和2的
# 3 c
# 2 a
# dtype: object
2. loc & iloc - 显式与隐式索引器
作用:用于对 Series (以及 DataFrame) 进行切片和索引提取。由于 Pandas 的索引既有"显式标签(如字符串键)“,又有系统隐含的"隐式整数顺序”,为了避免切片时的混乱,专门提供了这两个索引器。
loc:完全基于"显式索引(标签)"进行提取。注:使用 loc 切片时,是左闭右闭区间(包含结束值)!iloc:完全基于"隐式索引(物理位置/整数顺序)"进行提取。注:使用 iloc 切片时,是左闭右开区间(不包含结束值)!
Series.loc[label_indexer]
Series.iloc[integer_indexer]
参数:
- 显式标签 (label_indexer):
loc接收的具体标签名称或标签切片范围(Any / slice)。 - 整数位置 (integer_indexer):
iloc接收的具体整数位置或整数切片范围(int / slice)。
返回值:
- 成功: 返回提取出的单一元素(scalar)或部分数据的切片视图(Series)。
示例:
s = pd.Series(['a', 'b', 'c'], index=[1, 3, 5])
# loc 显式索引(根据具体的标签名找)
s.loc[1] # 返回 'a'
s.loc[1:3] # 返回 index为1和3的切片(左闭右闭)
# iloc 隐式索引(根据物理顺序找)
s.iloc[1] # 返回'b'(物理位置第 2 个)
s.iloc[1:3] # 返回物理位置1到2的切片(左闭右开)
3. get - 安全获取元素
作用:类似于字典的 get 方法,用于安全地获取Series中指定索引的值。与直接使用 [] 或 loc 索引不同,当对应的索引不存在时,它不会报错(KeyError),而是返回指定的默认值。
Series.get(key, default=None)
参数:
- 键 (key): 需要查找的目标索引标签(Any)。
- 默认值 (default): 可选参数,当查找的索引不存在时返回的默认值(Any)。如果不写,默认返回
None。
返回值:
- 成功: 索引存在时返回对应的值(scalar / Series);索引不存在时返回设定的默认值(Any)。
示例:
s = pd.Series([10, 20, 30], index=['a', 'b', 'c'])
# 1. 索引存在,正常返回对应的值
s.get('a') # 返回 10
# 2. 索引不存在,不写第二个参数,无显式报错和输出 (默认返回 None)
s.get('d') # 返回 None
# 3. 索引不存在,返回人为指定的默认值
s.get('d', 0) # 返回 0
4. rename - 重命名Series
作用:对现有的 Series 对象的名称(name)或索引进行重命名。注:这会返回一个新的对象,原对象不受影响!
Series.rename(index=None, **kwargs)
参数:
- 新名称 (index / 传入单个字符串): 若直接传入字符串,通常用于修改 Series 整体的
name属性(str 或 dict)。
返回值:
- 成功: 返回修改名称后的全新 Series 对象(Series)。
示例:
s = pd.Series([1, 2, 3], name="original_name")
# 修改 Series 的名字
s2 = s.rename("different_name")
# 原 s 的名字依然是 "original_name",s2 的名字为 "different_name"
5. copy - 对象的深拷贝
作用:创建一个数据和索引都完全独立的 Series 副本,避免修改新对象时影响原对象。
Series.copy()
参数:
- 无参数。
返回值:
- 成功: 返回一个内存地址完全独立的新 Series 对象(Series)。
示例:
s = pd.Series([1, 2, 3])
s_copy = s.copy()
6. in 关键字 - 判断索引是否存在
作用:用于判断给定的标签是否存在于 Series 的索引 (Index) 中。注:由于 Series 在很多时候表现得像 Python 字典,直接使用 in 关键字检查的是 Series 的"索引 (键)“,而不是具体的"值”!如果要检查值,需要配合 .values 属性。
label in Series
value in Series.values
参数:
- 标签/值 (label/value): 需要判断的目标对象(Any)。
- 序列 (Series / Series.values): 参与查找的 Pandas 序列对象或其底层的 NumPy 数组。
返回值:
- 成功: 存在返回布尔值
True,不存在返回False(bool)。
示例:
s = pd.Series([0.25, 0.5, 0.75], index=['a', 'b', 'c'])
# 1. 检查索引是否存在 (类似于字典检查键)
'a' in s # 返回 True
'd' in s # 返回 False
# 2. 检查具体的值是否存在 (需借助 .values)
0.5 in s.values # 返回 True
1.0 in s.values # 返回 False
7. 索引对齐 & 数据自动对齐
作用:当对两个 Series 进行算术运算(如加减乘除)时,Pandas 会自动根据索引标签进行对齐。计算结果将包含两个Series索引的并集。如果在任意一个 Series 中找不到某个标签,该位置的结果将被标记为 NaN (缺失值)。
注:默认产生索引并集是为了避免信息丢失,因为索引标签本身就是重要的元数据。如果需要,可以使用 .dropna() 方法删除包含 NaN 的标签。
参数:
- *无特定函数参数,属于 Series 间的算术运算符(+, -, , /)。
返回值:
- 成功: 返回一个索引为并集、值经过对齐计算后的新 Series 对象(Series)。
示例:
A = pd.Series([2, 4, 6], index=[0, 1, 2])
B = pd.Series([1, 3, 5], index=[1, 2, 3])
# 执行加法:索引 1, 2 匹配成功进行相加,0, 3 不匹配变为 NaN
res = A + B
# 0 NaN
# 1 5.0
# 2 9.0
# 3 NaN
# dtype: float64
# 使用 .dropna() 删除缺失数据
res.dropna()
# 1 5.0
# 2 9.0
# dtype: float64
8. 算术运算方法 (add, sub, mul, div)
作用:对应基础的算术运算符(+ 相加, - 相减, * 相乘, / 相除)。
当直接使用符号运算时,Pandas 会按索引自动对齐并执行"逐元素"的数学计算:相同索引的值会进行对应的加减乘除,而遇到不对齐的索引(即某一方缺失),该位置的计算结果必定为 NaN(缺失值)。虽然直接使用符号很方便,但使用这些显式方法(add等)的最大优势在于:它们允许你通过 fill_value 参数为缺失方提供一个默认数值参与计算,从而有效避免结果变成 NaN。
Series.add(other, fill_value=None) # 对应 +
Series.sub(other, fill_value=None) # 对应 -
Series.mul(other, fill_value=None) # 对应 *
Series.div(other, fill_value=None) # 对应 /
参数:
- 其他对象 (other): 参与运算的另一个 Series 或标量数值(Series / scalar)。
- 填充值 (fill_value): 可选参数。当两个 Series 索引不对齐时,用于代替缺失值的默认数值(float / int)。
返回值:
- 成功: 返回计算后的全新 Series 对象(Series)。
示例:
A = pd.Series([2, 4, 6], index=[0, 1, 2])
B = pd.Series([1, 3, 5], index=[1, 2, 3])
# 1. 直接使用符号运算 (相同索引相加,不对齐处直接变成 NaN)
A + B
# 0 NaN (A有值2,B缺失 -> NaN)
# 1 5.0 (4 + 1)
# 2 9.0 (6 + 3)
# 3 NaN (B有值5,A缺失 -> NaN)
# dtype: float64
# 2. 使用显式方法并指定 fill_value=0
# 逻辑:对于索引 0,A有值(2),B缺失。先用 0 填充B的缺失位置,再计算 2 + 0 = 2.0
A.add(B, fill_value=0)
# 0 2.0
# 1 5.0
# 2 9.0
# 3 5.0 (逻辑同上:A缺失用0填充,0 + 5 = 5.0)
# dtype: float64
9. 缺失值检测 - isna, notna
作用:专门用于检测 Series 中是否存在缺失值(NaN/None)。它们会逐元素进行判断,并返回一个与原 Series 长度相同的布尔型(True/False) Series。这通常是进行数据清洗和“布尔索引”的重要预备步骤。
isna()(等同于isnull()):如果是缺失值返回True,正常数据返回False。notna()(等同于notnull()):如果是正常数据返回True,缺失值返回False。
Series.isna()
Series.notna()
参数:
- 无特定核心参数。
返回值:
- 成功: 返回一个由
True和False组成的全新布尔型 Series 对象(Series)。
示例:
s = pd.Series([10, np.nan, 30])
s.isna()
# 0 False
# 1 True (是缺失值)
# 2 False
# dtype: bool
s.notna()
# 0 True (是正常数据)
# 1 False
# 2 True
# dtype: bool
10. 布尔索引 & 逻辑运算符(&, |, ~)
作用:布尔索引是 Pandas 中最强大的数据筛选方式之一。它允许我们把布尔型 Series(如条件判断结果、notna()结果)作为"掩码/钥匙"传回给原数据 Series[bool_mask],从而只提取出对应位置为 True 的数据。
当需要组合多个条件时,对应逻辑运算中的"与(&)”、“或(|)”、“非(~)”。注:在 Pandas 中做多条件逻辑筛选时,绝不能使用 Python 原生的 and 和 or 关键字!必须使用 & 和 |,并且每一个独立的条件判断都必须用括号 () 包裹起来。
Series[condition] # 单条件筛选
Series[(cond1) & (cond2)] # 多条件筛选 - 逻辑与 (且)
Series[(cond1) | (cond2)] # 多条件筛选 - 逻辑或 (或)
Series[~(condition)] # 多条件筛选 - 逻辑非 (取反)
参数/条件:
- 条件 (condition / cond1, cond2): 返回布尔值(Boolean)的条件表达式或 Series对象。
返回值:
- 成功: 返回一个筛选后的全新 Series 对象,内部只保留条件判断为
True的数据(Series)。
示例:
# 1. 常规的单/多重条件数值筛选
s = pd.Series([10, 20, 30, 40, 50], index=['a', 'b', 'c', 'd', 'e'])
# 筛选出大于15且小于45的值 (注意:多条件必须加括号!)
condition = (s > 15) & (s < 45)
# a False
# b True
# c True
# d True
# e False
# dtype: bool
s[condition]
# b 20
# c 30
# d 40
# dtype: int64
# 2. 结合预备函数 notna() 与 & 实现寻找共同数据的交集
s1 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
s2 = pd.Series([2, 3, 4], index=['b', 'c', 'd'])
align_df = pd.DataFrame({'s1': s1, 's2': s2})
# 找出 s1 和 s2 都不为空(notna)的位置
bool_mask = align_df['s1'].notna() & align_df['s2'].notna()
s1[bool_mask]
# b 2.0
# c 3.0
# dtype: float64
四.Index
Index (索引对象) 可以被看作是一个不可变数组(Immutable Array)或者一个有序集合(Ordered Set);也可以通过切片获取数值。
Index主要用于负责存储和管理 Pandas 对象的轴标签和其他元数据。
Index对象的不可变特征使得多个DataFrame和数组之间进行索引共享时更加安全,尤其是可以避免因修改索引时粗心导致的副作用。
0. Index属性
Index 对象最核心的四个属性(调用时不加括号):
size:返回Index中元素的总个数(整数)。shape:返回Index的形状,格式为元组(tuple)。ndim:返回Index的维度数(整数,通常为1)。dtype:返回Index内部元素的数据类型对象(dtype)。
1. Index - 创建索引对象
作用:创建 Pandas 的独立索引对象。注:Index 对象的元素是不支持被直接赋值修改的!这保证了在多个 DataFrame/Series 之间共享同一索引时的绝对安全。
pd.Index(data=None, dtype=None, name=None)
参数:
- 数据 (data): 用于创建索引的一维可迭代对象(array-like)。
- 数据类型 (dtype): 可选参数,强制指定数据类型(dtype)。
- 名称 (name): 可选参数,为索引对象命名(str)。
返回值:
- 成功: 返回一个不可变的索引对象(Index)。
示例:
ind = pd.Index([2, 3, 5, 7, 11])
# 获取属性 (与 NumPy 数组极其类似)
ind.size # 返回 5
ind.shape # 返回 (5,)
ind.ndim # 返回 1
ind.dtype # 返回 dtype('int64')
# 试图修改会直接报错:TypeError: Index does not support mutable operations
# ind[1] = 0
2. 集合运算 - 索引的交、并、补、差
作用:由于 Index 被设计为类似于有序集合,因此它原生支持集合运算,方便我们对不同数据集的索引进行合并、提取或对比。
注:在 Pandas 的较新版本中,使用符号 (&, |, ^) 进行 Index 集合运算的语法已被官方弃用(Deprecated),未来会被直接删掉!为了保证代码的安全性和版本兼容性,请务必改用显式的对象方法。
idxA.intersection(idxB) # 交集 (旧语法:idxA & idxB)
idxA.union(idxB) # 并集 (旧语法:idxA | idxB)
idxA.symmetric_difference(idxB) # 对称差集/异或 (旧语法:idxA ^ idxB)
idxA.difference(idxB) # 差集 (提取A中有但B中没有的,旧语法不支持)
参数:
idxB: 参与运算的另一个 Pandas 索引对象(Index)或可迭代对象。
返回值:
- 成功: 返回集合运算后的新索引对象(Index)。
示例:
indA = pd.Index([1, 3, 5, 7, 9])
indB = pd.Index([2, 3, 5, 7, 11])
# 交集:提取共同拥有的索引
indA.intersection(indB) # 返回 Index([3, 5, 7], dtype='int64')
# 并集:提取全部索引并去重
indA.union(indB) # 返回 Index([1, 2, 3, 5, 7, 9, 11], dtype='int64')
# 对称差集:提取各自独有、非共有的索引
indA.symmetric_difference(indB) # 返回 Index([1, 2, 9, 11], dtype='int64')
# 差集:提取在 indA 中,但不在 indB 中的索引
indA.difference(indB) # 返回 Index([1, 9], dtype='int64')
五.DataFrame
DataFrame可看作是一种既有灵活的行索引(Index),又有灵活列名(Columns)的二维数组;也可以被看成是有序排列的若干 Series对象的集合(这些 Series 共享同一个行索引)。
即:DataFrame = Index + 二维ndarry 或 DataFrame = n个Series。
0. DataFrame属性
DataFrame 的四大核心属性(调用时不加括号):
values:返回内部二维数据的 NumPy 数组表示(ndarray)。index:返回行索引(Index)。columns:返回列名/列标签(Index)。
-
dtypes:返回DataFrame中每一列的数据类型(返回一个Series,索引为列名,值为各列对应的 dtype)。# 1. 创建一个 Series s = pd.Series([10, 20, 30]) print(s.dtype) # 输出结果: int64 (直接返回了这唯一的一个类型) # 2. 创建一个 DataFrame df = pd.DataFrame({ '年龄': [25, 30], # 这一列是整数 '姓名': ['张三', '李四'] # 这一列是字符串 }) print(df.dtypes) # 输出结果: # 年龄 int64 # 姓名 object # dtype: object (返回了一个列出所有列类型的清单)
其他属性补充(基本与 NumPy 数组和 Series 的部分属性保持一致):
1. 形状与大小
size:返回 DataFrame 中元素的总个数(整数,即行数 × 列数)。shape:返回 DataFrame 的形状,格式为元组(例如(n_rows, n_columns))。ndim:返回 DataFrame 的维度数(整数,DataFrame 始终是二维的,返回2)。2. 结构与转置
axes:返回一个包含 DataFrame 两个轴标签的列表(即[index, columns])。T:返回 DataFrame 的转置(行变列,列变行,非常常用)。3. 数据状态检测与元数据
empty:判断 DataFrame 是否为空(返回布尔值True或False)。attrs:返回或设置与该 DataFrame 相关的全局元数据(返回一个字典,供用户存储自定义信息)。
(注意:DataFrame 没有 Series 的 hasnans, is_unique, is_monotonic_increasing 等针对一维数据的直接属性,通常需要针对具体某一列(也就是 Series)去调用这些属性。)
1. DataFrame - 创建二维数据表格
核心逻辑:
1. 只要最外层是“列表/数组”,往往是“按行”一层层铺进去的。
2. 只要最外层是“字典”,字典的""键(Key)“往往就会变成"列名(Columns)”。
口诀:列表按行铺,字典按列插。Series的index永远跟着数据走!”
- 如果数据变成了一行(列表),那数据的内部标签(index)自然就成了列名。
- 如果数据变成了一列(字典),那数据的内部标签(index)自然就成了行号。
作用:将各种数据结构转化为 DataFrame 二维表格。
核心特性:自动对齐与缺失值处理。当从多个字典或 Series 组合创建时,如果存在键或索引不齐的情况,Pandas 会自动使用 NaN (缺失值) 来补齐表格!
pd.DataFrame(data=None, index=None, columns=None, dtype=None)
参数说明:
-
行索引 (index): 可选,手动指定行标签。如果不写,默认生成从 0 开始的数字。(array-like / Index)
注: 行标如果位数不匹配,则会报错。data = [[1, 2], [3, 4]] # 这里的数据只有2行 # 我们强行给它指定 3 个行索引 df = pd.DataFrame(data, index=['a', 'b', 'c']) # 结果:代码崩溃,直接引发 ValueError 报错! # 报错信息类似于:ValueError: Shape of passed values is (2, 2), indices imply (3, 2) # (系统提示:你传进来的数据是2行2列,但你给的索引却暗示有3行,对不上号) -
列标签 (columns): 可选,手动指定列名。(array-like / Index)
注: 在创建df的过程中,对于已有列标的对象,column参数实际上相当于是找出对应的列并组成df。data = {'A': [1, 2], 'B': [3, 4], 'C': [5, 6]} # 原始数据有 A, B, C。我们指定 columns 只要 B, C,外加一个不存在的 D df = pd.DataFrame(data, columns=['B', 'C', 'D']) # B C D # 0 3 5 NaN # 1 4 6 NaN # 结果:'A'列被过滤去掉了;'D'列找不到数据,自动用 NaN 填充。 -
数据类型 (dtype): 可选,强制指定整体的数据类型。(dtype)
-
数据 (data): 最核心的参数!根据传入数据类型的不同,Pandas 的解析逻辑分为以下四种:
-
二维数组 / 嵌套列表(
ndarray/list[list]) -> 按行填充逻辑:最符合人类直觉的填表方式。外层列表代表整个表,里面的每一个子列表/子数组,代表表格中的一行。
-
字典的列表(
list[dict]) -> 按行填充,键变列名逻辑:列表里的每一个字典,代表表格中的一行。Pandas 会自动把所有字典的“键”收集起来去重,变成表格的列名。(如果没有对应的键,就填入
NaN)。 -
Series 列表(
list[Series]) -> 按行填充,索引变列名逻辑:和字典列表高度相似。列表里的每个 Series 代表一行。各个 Series 的
index会自动汇总对齐变成列名。如果 Series 有name属性,这个name会自动变成行索引。(对不齐的地方填入NaN)。 -
Series构成的字典(
dict[Series]) -> 按列填充,索引对齐逻辑:字典的“键”直接变成列名。字典的值(也就是那一串 Series)变成这一列的所有数据。多个 Series 会根据它们的行索引自动对齐拼在一起。(对不上的地方填入
NaN)。 -
单一 Series(
Series) -> 转为单列逻辑:一维的 Series 直接升维变成二维表格中唯一的一列。Series 的索引变成行索引,如果建表时不指定列名,会默认拿 Series 原本的
name属性作为列名。
代码示例对比(请对应上面的 4 种场景看):
# 1.由二维NumPy数组/嵌套列表创建(按行填充)
arr = np.random.rand(3, 2)
df1 = pd.DataFrame(arr, columns=['first', 'second'], index=['a', 'b', 'c'])
# first second
# a 0.607101 0.972586
# b 0.810251 0.496853
# c 0.997797 0.984033
# 2.由字典列表创建(每个字典是一行,键是列名)
data_list = [{'a': 1, 'b': 2},
{'b': 3, 'c': 4}] # 第一行没c,第二行没a
df2 = pd.DataFrame(data_list)
# a b c
# 0 1.0 2 NaN
# 1 NaN 3 4.0
# 3.由Series列表创建(每个Series是一行,name变行索引)
s1 = pd.Series([1, 2, 3], index=['a', 'b', 'c'], name="Row1")
s2 = pd.Series([2, 3, 4], index=['b', 'c', 'd'], name="Row2")
df3 = pd.DataFrame([s1, s2])
# a b c d
# Row1 1.0 2.0 3.0 NaN
# Row2 NaN 2.0 3.0 4.0
# 4.由Series字典创建(每个键是一列,Series索引变行标签)
pop_s = pd.Series({'A': 1, 'B': 2})
area_s = pd.Series({'A': 3, 'B': 4})
df4 = pd.DataFrame({'first': pop_s, 'area': area_s})
# population area
# A 1 3
# B 2 4
# 5.由单个Series创建(变成只有一列的 DataFrame)
s = pd.Series({'A': 1, 'B': 2})
df5 = pd.DataFrame(s, columns=['population'])
# population
# A 1
# B 2
2. head & tail - 快速查看数据
作用:对于行数非常多的 DataFrame,可以快速查看数据集的头部(前几行)或尾部(后几行)数据,以初步了解数据结构。
DataFrame.head(n=5)
DataFrame.tail(n=5)
参数:
- 行数 (n): 想要查看的具体行数,默认为 5 行(int)。
返回值:
- 成功: 返回包含指定行数的 DataFrame 切片(DataFrame)。
示例:
# 假设 df 是一个包含 100 行数据的表格
df.head() # 查看前 5 行
df.tail(10) # 查看最后 10 行
3. keys & values & [] & del/pop - 类字典使用方法
作用:Pandas 将 DataFrame 视作以“列名”为键,以“整列(Series)”为值的特殊字典。因此可以像操作字典一样去操作 DataFrame。
DataFrame.keys()
DataFrame.values
DataFrame['列名称']
del DataFrame['列名称']
DataFrame.pop('列名称')
返回值:
-
keys(): 返回 DataFrame 的列索引(Index),等同于DataFrame.columns。 -
values: 返回剥离了行列标签后,纯纯的二维内部数据(ndarray)。 -
DataFrame['列名称']: 返回对应列完整的Series。DataFrame['列名称'] = Series/列表/标量可以像字典一样直接新增一列。- 如果等号右边是标量(单个数值或字符串),它会自动在这一列的每一行里进行广播填充!
- 如果等号右边是列表,长度必须和 DataFrame 的行数严格一致。
- 如果等号右边是 Series 并且索引不完全相同,那么会默认按照索引对齐 (对不上的填 NaN,多出来的直接丢弃)!
# 1. 标量广播:这一列的所有行都会变成 'Yes' df['VIP'] = 'Yes' # 2. 列表赋值:长度必须和 df 的行数一致 df['Score'] = [90, 85, 88, 92] # 3. Series赋值(索引对齐):假设原 df 索引是 0, 1, 2, 3 s_new = pd.Series([10, 20, 30], index=[1, 2, 5]) df['Level'] = s_new # 结果:df 的行索引 1, 2 会分别填入 10.0, 20.0; # 行 0, 3 找不到对应数据,填入 NaN;Series 里多余的行 5 会被直接无视丢弃。 -
del DataFrame['列名称']或DataFrame.pop('列名称')可以像字典一样删除指定列。区别在于pop会把删掉的那一列作为返回值,而del只是默默删除。
示例:
d = {'one' : [1., 2., 3., 4.],
'two' : [4., 3., 2., 1.]}
df = pd.DataFrame(d)
# one two
# 0 1.0 4.0
# 1 2.0 3.0
# 2 3.0 2.0
# 3 4.0 1.0
df.keys()
# Index(['one', 'two'], dtype='object')
df.values
# [[1. 4.]
# [2. 3.]
# [3. 2.]
# [4. 1.]]
# 单独某一列的提取,得到的是 Series 数据类型
df['one']
# 0 1.0
# 1 2.0
# 2 3.0
# 3 4.0
# Name: one, dtype: float64
# 新增一列 (基于已有列进行运算赋值)
df['three'] = df['one'] * df['two']
# one two three
# 0 1.0 4.0 4.0
# 1 2.0 3.0 6.0
# 2 3.0 2.0 6.0
# 3 4.0 1.0 4.0
# 新增一列 (标量广播填充)
df['flag'] = 100
# one two three flag
# 0 1.0 4.0 4.0 100
# 1 2.0 3.0 6.0 100
# 2 3.0 2.0 6.0 100
# 3 4.0 1.0 4.0 100
# 删除一列
del df['three']
# one two flag
# 0 1.0 4.0 100
# 1 2.0 3.0 100
# 2 3.0 2.0 100
# 3 4.0 1.0 100
4. insert - 插入指定位置的新列
作用:用于在 DataFrame 的指定确切物理位置(索引)插入一列全新的数据。相比于直接使用 df['新列名'] = ... 默认把列加在表格最后,insert 方法可以自由控制新列的排版位置。注:此方法会直接在原对象上进行原地修改(In-place),无返回值!
DataFrame.insert(loc, column, value, allow_duplicates=False)
参数:
- **插入位置 (loc): 表示要插入的列索引位置(0 <= loc <= len(columns))。**例如
0代表插入到第一列。(int) - 列名称 (column): 插入的新列的标签名。(str / Any)
- 数据 (value): 插入的具体数据。可以是标量(自动广播)、Series 或与行数相等的列表/数组。(scalar / Series / array-like)
- 允许重名 (allow_duplicates): 默认不允许插入与现有列同名的新列,若设为
True则允许。(bool,默认为 False)
返回值:
- 成功: 无返回值 (NoneType)。该操作直接修改原 DataFrame 对象。
示例:
df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
# A B
# 0 1 3
# 1 2 4
# 在索引为 1 的位置(即第二列)插入名为 'New_Col' 的新列,内容全为 100
df.insert(loc=1, column='New_Col', value=100)
# 查看原 df,已经发生改变
# A New_Col B
# 0 1 100 3
# 1 2 100 4
5. assign - 链式添加新列
作用:用于为 DataFrame 分配(添加)新的列。与 insert 或直接赋值 df['新列'] = ... 的原地修改不同,assign 总是返回一个包含所有原列和新列的全新 DataFrame 对象,原对象不会被改变。这使得它非常适合用于连续的数据处理管道(链式编程)。
DataFrame.assign(**kwargs)
参数:
- 关键字参数 (**kwargs): 变量名即为新列的名称,变量值即为要插入的数据。数据可以是标量、Series、列表,或者是接收当前 DataFrame 作为输入并计算出新列的可调用对象(如 Lambda 表达式)。
返回值:
- 成功: 返回添加了新列后的全新 DataFrame 对象(DataFrame)。原数据表不受影响。
注意:
- 如果变量名是已经存在的列名,则覆盖对应的列
示例:
import pandas as pd
df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
# A B
# 0 1 3
# 1 2 4
# 方式1:直接传入具体数据 (标量或列表)
res1 = df.assign(C=[5, 6], D=100)
# A B C D
# 0 1 3 5 100
# 1 2 4 6 100
# 方式2:传入 Lambda 表达式进行动态计算 (非常推荐!)
# 这里的 x 指代的就是调用它的 df 对象本身
res2 = df.assign(Sum=lambda x: x['A'] + x['B'])
# A B Sum
# 0 1 3 4
# 1 2 4 6
# 注:执行后原 df 对象的数据完全没有改变!
6. loc & iloc - 显式与隐式二维切片
作用:这与 Series 中的用法完全一致,但由于 DataFrame 是二维的,因此可以在括号内同时传入“行标签”和“列标签”,用逗号分隔进行精确定位。
loc[行标签, 列标签]: 完全基于显式名称进行切片(左闭右闭)。iloc[行位置, 列位置]: 完全基于整数物理顺序切片(左闭右开)。
DataFrame.loc[row_indexer, column_indexer]
DataFrame.iloc[row_integer, column_integer]
参数:
- 行/列标签 (row_indexer, column_indexer): 用于定位的具体标签名或标签范围(Any / slice)。
- 行/列位置 (row_integer, column_integer): 用于定位的整数物理位置或范围(int / slice)。
返回值:
- 成功: 返回被精准切出的元素(scalar)、一整行/一整列(Series)或子表格(DataFrame)。
示例:
df = pd.DataFrame({'area': [100, 200, 300], 'pop': [10, 20, 30]}, index=['a', 'b', 'c'])
# loc 显式二维切片 (取 a行到b行,只取 'area' 列)
df.loc['a':'b', 'area']
# iloc 隐式二维切片 (取物理位置的 前两行,前一列)
df.iloc[:2, :1]
7. concat - Pandas 对象合并拼接
作用:将多个 Series 或 DataFrame 沿着特定轴拼接到一起。默认是上下拼接(按行),也可以指定左右拼接(按列)。
pd.concat(objs, axis=0, join='outer', ignore_index=False)
参数:
- 对象序列 (objs): 参与拼接的 Series 或 DataFrame 序列(list 或 tuple)。
- 轴 (axis): 0 代表上下拼接(增加行),1 代表左右拼接(增加列)(int,默认为0)。
- 合并方式 (join): 解决拼接时索引不对齐的问题。
outer取并集保留所有,inner取交集(str)。 - 忽略原索引 (ignore_index): 如果原索引无意义,设为
True则拼接后会重新生成 0, 1, 2… 的整数索引(bool)。
返回值:
- 成功: 返回合并后的新 Pandas 对象(Series 或 DataFrame)。
示例:
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
# 上下拼接(默认)
res1 = pd.concat([df1, df2])
# A B
# 0 1 3
# 1 2 4
# 0 5 7
# 1 6 8
# 上下拼接,且无视原索引,重新排序
res2 = pd.concat([df1, df2], ignore_index=True)
# A B
# 0 1 3
# 1 2 4
# 2 5 7
# 3 6 8
六. 数据的读取与写入(Data I/O)
Pandas 提供了极其强大的数据输入/输出 API,能够轻松地将本地文件、网络URL或数据库中的数据解析为DataFrame,也能将处理好的DataFrame导出为各种格式的文件。其中最常用的格式是CSV和Excel。
1. read_csv & to_csv - CSV文件的读写
csv格式文件也就是用逗号分隔的文本文件
作用:
read_csv用于读取以逗号分隔的文本文件(.csv)并转化为DataFrame;to_csv用于将DataFrame的数据导出并保存为CSV文件。
pd.read_csv(filepath_or_buffer, sep=',', header='infer', index_col=None, encoding=None)
DataFrame.to_csv(path_or_buf, sep=',', index=True, encoding='utf-8')
参数:
- 文件路径 (filepath_or_buffer/path_or_buf): 目标文件的本地绝对/相对路径,或者网络URL链接 (str或Path对象)。
- 分隔符 (sep): 文件中字段的物理分隔符。CSV 默认是逗号
,,如果是 TSV 文件通常是制表符\t(str)。 - 表头 (header):
read_csv中指定第几行作为列名。默认infer会自动推断首行。如果没有表头,需设为None(int 或 None)。 - 索引列 (index_col):
read_csv中指定将文件中的哪一列作为DataFrame的行索引(int或str)。如果不指定,Pandas 会自动生成 0, 1, 2… 的默认索引。 - 保留索引 (index):
to_csv中决定是否将 DataFrame 的行索引也写入文件中。通常如果是默认的 0,1,2… 索引,建议设为False(bool,默认为 True)。 - 字符编码 (encoding): 文件的文本编码格式。处理含有中文字符的文件时,常设为
'utf-8'或'gbk'以防止乱码 (str)。
返回值:
read_csv成功: 返回解析好数据的二维表格对象 (DataFrame)。to_csv成功: 默认将文件保存到本地,无返回值 (NoneType)。
示例:
import pandas as pd
# 1. 读取 CSV 文件
# 假设 'data.csv' 第一列是带有意义的 ID,我们将其指定为行索引,并且使用 gbk 解码中文
df = pd.read_csv('data.csv', index_col=0, encoding='gbk')
# 2. 导出为 CSV 文件
# 导出时不保留 Pandas 自动生成的数字行索引
df.to_csv('output_data.csv', index=False, encoding='utf-8')
2. read_excel & to_excel - Excel文件的读写
作用:read_excel 用于读取 Excel 文件(.xls, .xlsx)为 DataFrame;to_excel 用于将 DataFrame 导出为 Excel 文件。注:处理 Excel 文件通常需要底层依赖库(如 openpyxl 或 xlrd),若报错提示缺少库,需先使用 pip 安装。
pd.read_excel(io, sheet_name=0, header=0, index_col=None)
DataFrame.to_excel(excel_writer, sheet_name='Sheet1', index=True)
参数:
- 文件路径 (io / excel_writer): 目标 Excel 文件的路径(str或Path对象)。
- 工作表名称 (sheet_name): 指定要读取或写入的是哪一个 Sheet 工作表。可以通过字符串指定表名,或通过整数指定索引(0 表示第一个 Sheet) (str 或 int,默认为 0 / ‘Sheet1’)。
- 表头与索引列 (header, index_col, index): 用法与
read_csv/to_csv完全一致。
返回值:
read_excel成功: 返回提取出的工作表数据 (DataFrame)。如果在sheet_name传入列表或None,则返回包含多个 DataFrame 的字典 (dict)。to_excel成功: 默认将文件保存到本地,无返回值 (NoneType)。
示例:
# 1. 读取 Excel 文件中的第二个 Sheet 工作表(索引为 1)
df_excel = pd.read_excel('sales_report.xlsx', sheet_name=1)
# 2. 将 DataFrame 导出为 Excel,并命名工作表为 'Summary'
df_excel.to_excel('final_report.xlsx', sheet_name='Summary', index=False)
3. 其他常见格式的读写 API (拓展补充)
Pandas 支持的格式远不止 CSV 和 Excel,它们的参数逻辑与前两者高度相似,可根据实际业务需求调用:
- JSON 文件:
pd.read_json()/DataFrame.to_json() - HTML 表格:
pd.read_html()/DataFrame.to_html()(常用于简单的网络爬虫,直接提取网页中的<table>标签数据) - SQL 数据库:
pd.read_sql()/DataFrame.to_sql()(需配合SQLAlchemy等数据库连接引擎使用) - 剪贴板:
pd.read_clipboard()/DataFrame.to_clipboard()(极度实用的快捷技巧:在 Excel 中Ctrl+C复制一片区域,在 Python 中直接执行df = pd.read_clipboard()即可秒转为 DataFrame!)
更多推荐


所有评论(0)