目录

一、Pandas核心基础:核心数据结构

1. Series:一维带标签数组

2. DataFrame:二维表格型数据结构

3. Series与DataFrame常用基础操作

(1)Series常用操作

(2)DataFrame常用操作

二、Pandas核心操作理论:数据读取

1. 核心读取逻辑

2. CSV文件读取(常用)

3. Excel文件读取

三、Pandas核心操作理论:数据清洗

1. 缺失值处理

2. 重复值处理

3. 异常值处理

四、Pandas核心操作理论:分组统计

1. 分组统计核心逻辑(Split-Apply-Combine)

2. 分组条件的类型

3. 常用聚合操作

五、总结


学习目标:

        掌握Pandas基础核心知识,结合简单实操代码理解核心数据结构、数据读取、数据清洗及分组统计的用法,适合Pandas初学者入门;本文代码聚焦基础用法,避免复杂逻辑,帮助快速建立理论与实操的关联。

前置认知:

        Pandas是Python生态中用于数据处理与分析的核心库,专为结构化数据设计,能高效完成数据的读取、清洗、转换、统计等操作,是AI/数据分析学习的必备基础工具。

一、Pandas核心基础:核心数据结构

        Pandas的所有操作都基于两种核心数据结构,理解它们是掌握Pandas的前提,初学者需重点区分两者的定义、特点与适用场景。

1. Series:一维带标签数组

Series是由一组数据(可以是任意数据类型:整数、字符串、浮点数等)和一组与之对应的标签(索引,index)组成的一维数据结构,可理解为“带索引的数组”。

示例代码:

import pandas as pd
# 默认索引(0、1、2...)的Series
s1 = pd.Series([18, 20, 2.2, 19])
# 自定义索引的Series(索引为姓名)
s2 = pd.Series([85, 92, 78, 90], index=["张三", "李四", "王五", "赵六"])
print(s1)
print(s2)
print(s2.shape)
print(s2.index)
print(s2.values)

运行结果:

0    18.0
1    20.0
2     2.2
3    19.0
dtype: float64

张三    85
李四    92
王五    78
赵六    90
dtype: int64

s2的数据长度: (4,)
s2的索引: Index(['张三', '李四', '王五', '赵六'], dtype='object')
s2的数据值: [85 92 78 90]

核心特点:

  • 索引唯一:索引是Series的核心标识,用于数据定位。

  • 数据类型灵活:单个Series可容纳一种数据类型,不同Series的数据类型可不同。

  • 自带属性:拥有dtype(数据类型)、shape(数据长度)、index(索引)、values(数据值)等属性,可快速获取数据基本信息。

适用场景:存储单一维度的数据,如某班级所有学生的年龄、某商品的月度销量等。

2. DataFrame:二维表格型数据结构

        DataFrame是由多个Series按列组合而成的二维数据结构,包含行索引(index)和列索引(columns),可理解为“带索引的Excel表格”,是Pandas中最常用的数据结构。

示例代码:

import pandas as pd
# 用字典创建DataFrame(键为列名,值为对应列的Series数据)
data = {
    "姓名": ["张三", "李四", "王五", "赵六"],
    "年龄": [18, 20, 22, 19],
    "成绩": [85, 92, 78, 90]
}
df = pd.DataFrame(data)
print(df)

# 从DataFrame中提取某一列(即Series)
age_series = df["年龄"]
print(age_series)

运行结果:

   姓名  年龄  成绩
0  张三  18  85
1  李四  20  92
2  王五  22  78
3  赵六  19  90

0    18
1    20
2    22
3    19
Name: 年龄, dtype: int64

核心特点:

  • 二维结构:既有行索引也有列索引,行索引标识行数据,列索引标识列数据(即对应的Series)。

  • 列类型可多样:不同列(Series)的数据类型可不同(如一列是字符串、一列是整数、一列是浮点数)。

  • 可灵活扩展:支持新增/删除行、列,也可修改索引和列名,适配数据处理过程中的各种需求。

  • 集成Series特性:每一列都是一个Series,可通过列名快速提取对应列的数据进行单独处理。

适用场景:存储结构化数据,如学生信息表(含姓名、年龄、成绩等列)、商品数据表(含名称、价格、销量等列),是后续数据处理、统计的主要载体。

3. Series与DataFrame常用基础操作

(1)Series常用操作

        核心聚焦索引定位、数据筛选和简单计算,代码示例如下:

# 延续前文创建的s2(姓名为索引,成绩为数据)
import pandas as pd
s2 = pd.Series([85, 92, 78, 90], index=["张三", "李四", "王五", "赵六"])

# 1. 索引定位(两种核心方式)
print(s2["张三"])  # 标签索引(自定义索引) 预期输出:85
print(s2[0])       # 位置索引(默认整数位置,从0开始) 预期输出:85

# 2. 数据筛选(按条件过滤)
print(s2[s2 > 85])  # 筛选成绩大于85的数据
"""
预期输出:
李四    92
赵六    90
dtype: int64
"""

print(s2[["张三", "赵六"]])  # 筛选指定索引的数据

# 3. 简单计算(自动对齐索引)
s3 = pd.Series([5, 3, 2, 1], index=["张三", "李四", "王五", "赵六"])
print(s2 + s3)  # 相同索引的数据相加,得到新Series

#关键说明:Series的索引定位是核心,标签索引和位置索引需区分清楚;条件筛选支持常见的比较运算符(>、<、==等)。

(2)DataFrame常用操作

        DataFrame核心包括行/列查看、数据筛选、简单新增/删除,代码示例如下:

import pandas as pd
data = {
    "姓名": ["张三", "李四", "王五", "赵六"],
    "年龄": [18, 20, 22, 19],
    "成绩": [85, 92, 78, 90]
}
df = pd.DataFrame(data)

# 1. 行/列基础查看
print(df.columns)  # 查看所有列名
print(df.index)    # 查看所有行索引
print(df.head(2))  # 查看前2行数据(默认前5行)
print(df.tail(2))  # 查看后2行数据

# 2. 数据筛选(按列、按行、按条件)
print(df["姓名"])          # 按列名筛选(提取Series)
print(df[["姓名", "成绩"]]) # 筛选多列(结果为DataFrame)
print(df.iloc[0])          # 按行位置筛选(第1行数据)
print(df[df["成绩"] > 85]) # 按条件筛选(成绩大于85的行)

# 3. 简单新增/删除列
df["排名"] = [3, 1, 4, 2]  # 新增"排名"列
print(df)
df_drop = df.drop("排名", axis=1)  # 删除"排名"列(axis=1表示按列删除)
print(df_drop)

        以上操作是日常数据处理的高频基础操作,建议结合代码反复练习,熟练掌握后能大幅提升数据处理效率。

二、Pandas核心操作理论:数据读取

        数据读取是数据处理的第一步,核心目标是将外部数据(如CSV、Excel文件)加载为Pandas的DataFrame格式,以便后续操作;Pandas支持多种数据格式,初学者需重点掌握CSV和Excel两种常用格式的读取逻辑。

1. 核心读取逻辑

        Pandas读取数据的本质:通过指定数据文件路径/URL、数据分隔符、索引列等参数,将外部结构化数据解析为DataFrame,核心是“参数匹配数据格式”——即根据外部数据的实际结构,设置对应的读取参数,确保数据正确加载。

2. CSV文件读取(常用)

        CSV(逗号分隔值)是最常见的结构化数据格式,数据以逗号为默认分隔符,每行代表一条数据,每列代表一个字段。

核心读取函数:read_csv(),初学者需掌握的核心参数:

  • filepath_or_buffer:数据路径,可以是本地文件路径(如“./data/titanic.csv”)或网络文件URL(如Hugging Face公开数据集链接)。

  • sep:数据分隔符,默认是逗号(,),若数据以其他符号分隔(如分号;、制表符\t),需手动指定(如sep=";")。

  • index_col:指定某一列作为行索引,默认不指定(行索引为0、1、2...),可提高数据定位效率。

  • header:指定表头行,默认header=0(第一行为列名),若数据无表头,需设置header=None,后续手动指定列名。

  • usecols:指定需要读取的列,可避免读取无用数据,提升效率(如usecols=["姓名","年龄","成绩"])。

        读取后核心验证逻辑:加载数据后需快速确认数据是否正确,核心方式包括:查看前几行数据(确认列名和数据格式)、查看数据基本信息(确认行数、列数、数据类型)、查看是否有缺失值(提前预判后续清洗需求)。

示例代码(本文章使用了huggingface的开源数据集:titanic):

import pandas as pd

# 方法1:读取本地CSV文件(需提前准备titanic.csv文件)
df = pd.read_csv("code/Pandas/data/titanic.csv")

# 也可直接使用url通过网络下载相关数据集
# 方式2:Pandas直接读取公开网络CSV URL
# 泰坦尼克号经典数据集的公开URL(GitHub开源仓库,稳定可用)
# titanic_url = "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"
# 直接读取网络CSV文件(无需本地下载,首次运行需联网)
# df = pd.read_csv(titanic_url)

# 方式3:Seaborn内置数据集
# df = sns.load_dataset('titanic')  # Seaborn内置泰坦尼克数据集,自动缓存本地

# 方式4:Hugging Face数据集快捷读取(需先安装datasets库)
# df = pd.read_csv("hf://datasets/ankislyakov/titanic/titanic.csv")

# 可将网络数据集保存到本地
# save_path = "code/Pandas/data/titanic.csv" #实操中记得替换为你实际的地址
# df.to_csv(save_path, index=False)  # index=False避免保存多余的索引列
# print("数据集已保存到本地:{save_path}")

# 核心验证操作
print(df.head())  # 查看前5行数据
print(df.info())  # 查看数据基本信息(行数、列数、数据类型、缺失值)
print(df.isnull().sum())  # 单独统计各列缺失值数量

3. Excel文件读取

Excel文件(.xlsx/.xls)是办公场景中常用的数据格式,支持多工作表存储数据,读取时需额外指定工作表信息。

核心读取函数:read_excel(),需掌握的核心参数(补充CSV读取未提及的关键参数):

  • sheet_name:指定读取的工作表,可传入工作表名称(如sheet_name="Sheet1")或索引(如sheet_name=0,默认读取第一个工作表)。

  • engine:读取引擎,默认自动选择,若出现读取报错,可手动指定(如读取.xlsx文件用engine="openpyxl",读取.xls文件用engine="xlrd")。

注意事项:读取Excel文件需提前安装对应的依赖库(如openpyxl、xlrd),否则会出现导入失败报错。

# 安装依赖(终端执行)
# pip install openpyxl
# 读取本地Excel文件
df_excel = pd.read_excel("titanic.xlsx", sheet_name="Sheet1")
print(df_excel.head())

三、Pandas核心操作理论:数据清洗

        数据清洗是数据处理的核心环节,目标是识别并处理数据中的“脏数据”(缺失值、重复值、异常值、不一致值等),得到干净、可用的标准化数据,为后续分析提供可靠基础;核心原则是“最小干预”,即尽量保留原始数据信息,避免过度处理导致数据失真。

1. 缺失值处理

        缺失值是指数据集中存在的空白或未记录的值(如未填写的年龄、缺失的成绩等),是最常见的“脏数据”类型,处理核心是“先识别,后针对性处理”。

(1)缺失值识别:核心思路是通过函数判断数据是否为缺失状态(Pandas中缺失值用NaN表示),常用方式包括:

# 以titanic数据集为例
df = pd.read_csv("code/Pandas/data/titanic.csv")

# 方式1:按列统计缺失值数量
print(df.isnull().sum())
# 方式2:查看缺失值分布(只显示有缺失值的行,前10行)
print(df[df.isnull().any(axis=1)].head(10))

按列统计缺失值数量:明确各字段的缺失程度,为处理方式选择提供依据。

查看缺失值分布:确认缺失值是随机分布还是集中分布(如某一类别数据集中缺失),避免处理后引入偏差。

(2)缺失值处理三大核心方式:

# 方式1:删除法 + 显式生成副本(避免Pandas视图/副本警告,新手必学)
df_clean1 = df.dropna(subset=["Embarked"]).copy()
# 方式2:插值法填充Age(用.loc赋值,明确行/列范围,编码更规范)
# 可选插值方式:linear(线性插值)、pad(向前填充)、bfill(向后填充)、quadratic(二次插值)等
df_clean1.loc[:, "Age"] = df_clean1["Age"].interpolate(method="linear") #线性插值(最常用)
# 方式3:填充法,为“Cabin”列的缺失值填充"Unknown"
df_clean1.loc[:, "Cabin"] = df_clean1["Cabin"].fillna("Unknown")
# 验证处理结果
print(df_clean1.isnull().sum())
  • 删除法:直接删除包含缺失值的行或列,适用于缺失值占比极低(如<5%)、且缺失数据对分析无影响的场景;注意避免大量删除数据导致样本量不足。

  • 填充法:用合理值替换缺失值,适用于缺失值占比中等(5%-30%)的场景,是最常用的处理方式:① 数值型数据:常用均值(适用于数据分布均匀)、中位数(适用于数据存在异常值)填充;② 分类型数据:常用众数(出现频率最高的值)或自定义默认值(如“Unknown”)填充。

  • 插值法:通过数据的趋势或关联关系估算缺失值(如线性插值、基于相邻数据的插值),适用于时间序列数据或存在明显关联的数值型数据,初学者可先掌握基础填充法,后续再深入学习。

2. 重复值处理

        重复值是指数据集中完全相同的行(所有字段值均一致),会导致统计结果失真(如重复计算同一数据),处理逻辑相对简单:“识别-删除”。

(1)重复值识别:通过函数判断每行数据是否与之前的行完全重复,统计重复值数量。

# 查看重复行数量
print(df_clean1.duplicated().sum())
# 查看具体重复行(若有)
print(df_clean1[df_clean1.duplicated()])

(2)重复值处理:核心方式是删除重复值,默认保留首次出现的行,删除后续重复行;特殊场景下可根据需求保留最后一次出现的行,或指定某几列作为判断重复的依据(而非所有列)。

# 删除重复行
df_clean2 = df_clean1.drop_duplicates()
# 验证重复值是否删除
print(df_clean2.duplicated().sum())  # 输出0表示无重复值

3. 异常值处理

        异常值是指偏离数据正常分布范围的值(如年龄200岁、成绩-10分等),会严重影响统计分析结果(如均值被拉高/拉低),处理核心是“先识别,后判断是否处理”。

(1)异常值识别:

# 方法1:统计描述法(查看Age列的统计信息)
print(df["Age"].describe())
# 方法2:四分位法定义Age列异常值条件
Q1 = df["Age"].quantile(0.25)       # 下四分位
Q3 = df["Age"].quantile(0.75)       # 上四分位
IQR = Q3 - Q1                       # 四分位距
lower_bound = Q1 - 1.5 * IQR        # 异常值下限
upper_bound = Q3 + 1.5 * IQR        # 异常值上限
abnormal_condition = (df["Age"] < lower_bound) | (df["Age"] > upper_bound)  # 异常值标记

print(f"Age列正常范围:{lower_bound:.2f} ~ {upper_bound:.2f}")
print(f"异常值数量:{df[abnormal_condition].shape[0]}")
print(f"异常值占比:{df[abnormal_condition].shape[0]/len(df)*100:.2f}%\n")

"""
预计输出:
统计描述法:
count    891.000000
mean      29.361582
std       13.019697
min        0.420000
25%       22.000000
50%       28.000000
75%       35.000000
max       80.000000
Name: Age, dtype: float64

四分位法:
Age列正常范围:2.50 ~ 54.50
异常值数量:66
异常值占比:7.41%
"""
  • 统计描述法:通过查看数据的统计信息(均值、标准差、最小值、最大值、四分位数等),判断是否存在超出合理范围的值(如年龄最大值为200,明显异常)。

  • 四分位法(IQR法):通过计算四分位距(IQR=上四分位Q3-下四分位Q1),定义异常值范围为“小于Q1-1.5*IQR”或“大于Q3+1.5*IQR”,该方法对数据分布要求低,适用性广。简单概括即:用数据的 “中间 50% 范围” 定义 “正常波动区间”,超出 1.5 倍区间的即为异常。

(2)异常值处理方式:

# 方法1:替换法
df_replace = df.copy()
age_median = df_replace["Age"].median()  # 用中位数替换
df_replace.loc[abnormal_condition, "Age"] = age_median
# 验证替换结果
replace_abnormal = (df_replace["Age"] < lower_bound) | (df_replace["Age"] > upper_bound)
print("===== 替换法处理结果 =====")
print(f"替换用的中位数:{age_median:.2f}")
print(f"替换后异常值数量:{df_replace[replace_abnormal].shape[0]}\n")

# 方法2:删除法
df_delete = df.copy()
df_delete = df_delete[~abnormal_condition]  # 保留非异常值
print("===== 删除法处理结果 =====")
print(f"删除前总行数:{len(df)}")
print(f"删除后总行数:{len(df_delete)}")
print(f"删除的异常值行数:{len(df)-len(df_delete)}\n")

# 方法3:修正法(截断到正常范围)
df_fix = df.copy()
df_fix.loc[df_fix["Age"] < lower_bound, "Age"] = lower_bound  # 低于下限→下限
df_fix.loc[df_fix["Age"] > upper_bound, "Age"] = upper_bound  # 高于上限→上限
# 验证修正结果
fix_abnormal = (df_fix["Age"] < lower_bound) | (df_fix["Age"] > upper_bound)
print("===== 修正法处理结果 =====")
print(f"修正后异常值数量:{df_fix[fix_abnormal].shape[0]}\n")

# 方法4:保留法(仅标注,不修改)
df_keep = df.copy()
df_keep["Age_Is_Abnormal"] = abnormal_condition  # 新增列标注异常值
print("===== 保留法处理结果 =====")
print("异常值标注列统计(正常/异常):")
print(df_keep["Age_Is_Abnormal"].value_counts())
  • 删除法:适用于异常值明确是错误数据(如录入错误)、且数量极少的场景。

  • 修正法:若异常值是可修正的错误(如将“200岁”修正为“20岁”),可通过人工核查或规则修正。

  • 替换法:用均值、中位数等合理值替换异常值,适用于异常值数量较少、但删除会影响样本完整性的场景。

  • 保留法:若异常值是真实存在的特殊情况(如某商品的极端高销量),需保留并在后续分析中单独标注说明。

四、Pandas核心操作理论:分组统计

        分组统计是数据分析的核心手段,核心思路是“按指定条件将数据分组,对每组数据进行聚合计算”,实现从整体数据到分组细节数据的挖掘,常用场景包括“按类别统计均值”“按时间段统计总和”等。

1. 分组统计核心逻辑(Split-Apply-Combine)

        Pandas的分组统计遵循“拆分-应用-合并”三步流程,是理解分组操作的关键:

# 以titanic清洗后的数据为例,按Sex分组统计Age的均值
# Split(拆分):按Sex拆分为男性和女性两个子DataFrame
# Apply(应用):计算每个子DataFrame中Age的均值
# Combine(合并):将结果合并为新的DataFrame
print("Step1:Split")
# 按Sex列把数据拆分成「女性组」和「男性组」
grouped = df.groupby("Sex")
for group_name, group_data in grouped:
    print(f"分组名称:{group_name},该组数据行数:{len(group_data)}")

print("\nStep2:Apply")
# 对每个分组的Age列,执行“计算均值”的操作
# 本质:分别算女性组Age均值、男性组Age均值
group_age_mean = grouped["Age"].mean()

print("\nStep3:Combine")
# 自动把两个分组的均值结果,合并成一个新的表格(Series)
print("按性别分组的Age均值最终结果:")
print(group_age_mean)

print("\n拓展:一次统计多个指标(均值+中位数)")
# Apply:同时计算均值和中位数
# Combine:合并成带列名的表格
group_age_stats = grouped["Age"].agg(["mean", "median"])
print("按性别分组的Age均值+中位数:")
print(group_age_stats)

运行结果:

Step1:Split
分组名称:female,该组数据行数:314
分组名称:male,该组数据行数:577

Step2:Apply

Step3:Combine
按性别分组的Age均值最终结果:
Sex
female    27.929936
male      30.140676
Name: Age, dtype: float64

拓展:一次统计多个指标(均值+中位数)
按性别分组的Age均值+中位数:
             mean  median
Sex
female  27.929936    28.0
male    30.140676    28.0

2. 分组条件的类型

        分组条件决定了数据的拆分方式,初学者需掌握三种常见分组类型:

# 1. 单一条件分组(按Sex分组,统计存活人数)
single_group = df.groupby("Sex")["Survived"].sum()
# 2. 多条件分组(按Sex+Pclass分组,统计存活人数)
multi_group = df.groupby(["Sex", "Pclass"])["Survived"].sum()
# 3. 自定义条件分组(按年龄范围分组,统计平均票价)
# 先定义分组规则
def age_group(age):
    if age < 18:
        return "未成年"
    elif 18 <= age <= 60:
        return "成年"
    else:
        return "老年"
# 新增年龄分组列
df["Age_Group"] = df["Age"].apply(age_group)
# 按自定义分组统计
custom_group = df.groupby("Age_Group")["Fare"].mean()

print("单一条件分组:")
print(single_group)
print("\n多条件分组:")
print(multi_group)
print("\n自定义条件分组:")
print(custom_group)

运行结果:

单一条件分组:
Sex
female    233
male      109
Name: Survived, dtype: int64

多条件分组:
Sex     Pclass
female  1         91
        2         70
        3         72
male    1         45
        2         17
        3         47
Name: Survived, dtype: int64

自定义条件分组:
Age_Group
成年     32.084434
未成年    31.220798
老年     41.371214
Name: Fare, dtype: float64
  • 单一条件分组:按某一个字段的值分组(如按“性别”分组、按“班级”分组),是最基础的分组方式。

  • 多条件分组:按多个字段的组合条件分组(如按“性别+舱位等级”分组、按“班级+学科”分组),可实现更细致的统计分析。

  • 自定义条件分组:按自定义规则分组(如按年龄范围分组:<18岁、18-30岁、>30岁;按数值区间分组:低、中、高),适用于需要灵活划分数据的场景。

3. 常用聚合操作

        聚合操作是分组后对每组数据的计算,核心是“对数值型数据进行汇总或描述”,常用聚合函数及用途:

# 按Sex分组执行多聚合操作
agg_result = df.groupby("Sex").agg(
    Age_mean=("Age", "mean"),
    Age_median=("Age", "median"),
    Age_max=("Age", "max"),
    Fare_sum=("Fare", "sum"),
    Fare_total_count=("Fare", "size"),  # size统计总行数(含缺失值),count只统计非空
    Survived_sum=("Survived", "sum")
)

# 打印结果
print("按性别分组的聚合统计结果:")
print(agg_result)

运行结果:

按性别分组的聚合统计结果:
         Age_mean  Age_median  Age_max    Fare_sum  Fare_total_count  Survived_sum
Sex
female  27.929936        28.0     63.0  13966.6628               314           233
male    30.140676        28.0     80.0  14727.2865               577           109
  • 基础统计聚合:sum(求和,如统计每组总销量)、mean(求均值,如统计每组平均年龄)、count(计数,如统计每组人数)、max(求最大值)、min(求最小值)、std(求标准差,反映数据离散程度)。

  • 进阶统计聚合:median(求中位数,适用于存在异常值的数据)、quantile(求四分位数,分析数据分布)、unique(统计每组唯一值,适用于分类型数据)、nunique(统计每组唯一值数量)。

五、总结

1. 核心数据结构:掌握Series(一维带标签数组)与DataFrame(二维表格数据)的定义、特点及关联,是学习Pandas的基础。

2. 数据读取:理解read_csv()/read_excel()的核心参数逻辑,明确“参数匹配数据格式”和“读取后验证”的重要性。

3. 数据清洗:掌握缺失值、重复值、异常值的“识别-处理”核心思路,牢记“最小干预”原则,根据数据情况选择合适处理方式。

4. 分组统计:理解“Split-Apply-Combine”三步流程,掌握常见分组条件和聚合操作,明确分组统计的核心目标是挖掘分组数据规律。

参考资料:Pandas官方文档:https://pandas.pydata.org/docs/

数据集资源:ankislyakov/titanic · Datasets at Hugging Face(需科学上网)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐