当前位置: 首页 > ops >正文

Python 数据分析与机器学习入门 (三):Pandas 数据导入与核心操作

引言:Pandas 是什么,为何如此重要?

如果说 NumPy 是处理原始数值数组的利器,那么 Pandas 则是驾驭结构化数据的瑞士军刀。在真实世界的数据分析项目中,数据很少是单纯的数字矩阵。它们通常以表格形式存在,包含行和列,每列可能有不同的数据类型(如文本、数字、日期),并且带有描述性的列名和行索引。Pandas 正是为高效处理这类数据而生。

Pandas 构建于 NumPy 之上,它不仅继承了 NumPy 的高性能计算能力,还提供了两种极为强大和灵活的数据结构:SeriesDataFrame。这使得数据清洗、转换、分析和可视化变得前所未有的简单和直观。对于任何数据分析师或科学家来说,精通 Pandas 是必备技能。

核心数据结构:Series 与 DataFrame

理解 Pandas 的第一步是掌握其两个核心数据结构。

Series

可以看作是一个一维带标签的数组。它类似于电子表格中的一列或数据库表中的一个字段。每个 Series 对象都由数据和与之关联的标签(即索引)组成。

import pandas as pd# 从列表创建 Series
s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])
print(s)
# 输出:
# a    10
# b    20
# c    30
# d    40
# dtype: int64

DataFrame

这是 Pandas 的核心,一个二维带标签的数据结构,可以看作是一个电子表格、一个 SQL 表,或者一个由多个 Series 对象组成的字典。

DataFrame 的每一列都可以是不同的数据类型。它有行索引和列索引。

# 从字典创建 DataFrame
data = {'State': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],'Year': [2000, 2001, 2002, 2001, 2002],'Population': [1.5, 1.7, 3.6, 2.4, 2.9]}
df = pd.DataFrame(data)
print(df)
# 输出:
#     State  Year  Population
# 0    Ohio  2000         1.5
# 1    Ohio  2001         1.7
# 2    Ohio  2002         3.6
# 3  Nevada  2001         2.4
# 4  Nevada  2002         2.9

关键关系:一个 DataFrame 是由多个 Series 共享同一个索引组成的。你可以将 DataFrame 的每一列都视为一个 Series

数据导入:pd.read_csv()

数据分析的第一步通常是加载数据。Pandas 提供了强大的 I/O 工具,可以轻松读取多种格式的文件,其中最常用的是 pd.read_csv()

# 从本地 CSV 文件加载数据
# 假设当前目录下有一个名为 'titanic.csv' 的文件
df_titanic = pd.read_csv('titanic.csv')

read_csv() 函数功能非常强大,拥有众多参数。对于初学者,掌握以下几个核心参数至关重要:

  • filepath_or_buffer: 文件的路径。这可以是一个本地文件路径,也可以是一个 URL。
  • sep (或 delimiter): 指定列之间的分隔符。默认是逗号 ,。如果文件是制表符分隔(TSV),则应设置为 sep='\t'
  • header: 指定哪一行作为列名。默认是 0(第一行)。如果文件没有列名,可以设置为 header=None
  • usecols: 一个列表,用于指定只加载哪些列。在处理大文件时,这可以显著节省内存和加载时间。例如:usecols=['Name', 'Age', 'Sex']
  • skiprows: 一个整数或列表,用于跳过文件开头的指定行数。
  • nrows: 只读取文件的前 n 行,这对于快速预览大文件非常有用。

基础检查:初探数据

加载数据后,第一要务是快速了解其概况。Pandas 提供了一系列简洁的方法来完成这项工作:

  • .head(n).tail(n): 查看数据的前 n 行或后 n 行(默认 n=5)。
    print(df_titanic.head())
    
  • .info(): 提供 DataFrame 的简明摘要,包括行数、列数、每列的非空值数量和数据类型。这是检查缺失值的首选方法
    df_titanic.info()
    
  • .describe(): 对数值型列生成描述性统计数据,如计数、均值、标准差、最小值、最大值和四分位数。
    print(df_titanic.describe())
    
  • .shape: 返回一个包含行数和列数的元组。
    print(df_titanic.shape)
    

数据选择:loc 与 iloc 的艺术

DataFrame 中精确地选取所需数据是数据处理的核心技能。Pandas 提供了两种主要的索引方法:.loc.iloc。理解它们的区别是成为 Pandas 高手的关键一步。

列选择

  • 选择单列(返回一个 Series):
    ages = df_titanic['Age']
    
  • 选择多列(返回一个 DataFrame):
    subset = df_titanic[['Name', 'Age', 'Sex']]
    

行选择:.loc vs. .iloc

这是初学者最容易混淆的地方。一个简单的原则是:.loc 是基于标签 (Label) 的,而 .iloc 是基于位置 (Integer position) 的。

.loc (基于标签)
  • 使用行和列的名称进行选择。
  • 切片操作是包含结束标签的。
# 选择索引标签为 0 的行
print(df_titanic.loc[0])# 选择索引标签为 0 到 4 的行,以及 'Name' 和 'Age' 列
print(df_titanic.loc[0:4, ['Name', 'Age']])
.iloc (基于位置)
  • 使用行和列的整数索引(从 0 开始)进行选择。
  • 切片操作不包含结束位置,与 Python 标准切片行为一致。
# 选择第一行 (位置 0)
print(df_titanic.iloc[0])# 选择前 5 行 (位置 0 到 4),以及第 4 和第 5 列 (位置 3 和 4)
print(df_titanic.iloc[0:5, [3, 4]]) 

为什么区分 lociloc 如此重要?

这不仅仅是语法上的差异,更关乎代码的健壮性可读性。当你使用 df.iloc[:, 2] 来选择第三列时,如果未来数据源的列顺序发生变化(例如,在前面插入了一列),你的代码就会在不报错的情况下默默地选择了错误的列。而如果你使用 df.loc[:, 'Age'],代码要么继续正确工作,要么在 ‘Age’ 列被重命名或删除时,会明确地抛出 KeyError 错误。这种明确性使得 .loc 在大多数情况下是更安全、更易于维护的选择

特性.loc.iloc
索引方法基于标签 (Label-based)基于位置 (Position-based)
输入类型行/列的名称(标签)行/列的整数位置
切片行为包含结束标签不包含结束位置
核心用途通过有意义的标签选择数据通过数字位置选择数据
示例df.loc['row_label', 'col_name']df.iloc[row_index, col_index]

条件选择 (Boolean Indexing)

这是数据筛选最强大、最常用的方式。它允许你根据列中的值来选择行。

# 选择所有年龄大于 30 岁的乘客
adults = df_titanic[df_titanic['Age'] > 30]# 结合多个条件 (使用 & 和 |,注意括号)
# 选择所有头等舱 (Pclass=1) 且年龄大于 30 的女性乘客
wealthy_women = df_titanic[(df_titanic['Pclass'] == 1) & (df_titanic['Sex'] == 'female') & (df_titanic['Age'] > 30)]
print(wealthy_women.head())

总结与展望

您现在已经掌握了使用 Pandas 加载、检查和选择数据的核心技能。这是进行任何数据分析的基础。我们学会了如何从文件中读取数据,如何快速评估数据质量,以及如何使用 .loc.iloc 和布尔索引精确地提取我们感兴趣的数据子集。

然而,真实世界的数据往往是“凌乱”的。它可能来自多个源头,需要合并;或者我们需要按类别进行汇总统计。在下一篇文章中,我们将学习 Pandas 更高级的功能:数据聚合与合并,这将使我们能够从原始数据中提炼出更有价值的洞见。

http://www.xdnf.cn/news/14725.html

相关文章:

  • 提示技术系列——链式提示
  • 现代 JavaScript (ES6+) 入门到实战(四):数组的革命 map/filter/reduce - 告别 for 循环
  • stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
  • 第二届 Parloo杯 应急响应学习——畸形的爱
  • 理解 Confluent Schema Registry:Kafka 生态中的结构化数据守护者
  • Qt事件系统
  • 机器学习在智能电网中的应用:负荷预测与能源管理
  • MySQL锁机制全解析
  • 06_注意力机制
  • Modbus 报文结构与 CRC 校验实战指南(一)
  • leetcode437-路径总和III
  • TVFEMD-CPO-TCN-BiLSTM多输入单输出模型
  • ASP.Net依赖注入!使用Microsoft.Extensions.DependencyInjection配置依赖注入
  • 【ad-hoc】# P12414 「YLLOI-R1-T3」一路向北|普及+
  • MyBatis批量删除
  • 现代 JavaScript (ES6+) 入门到实战(一):告别 var!拥抱 let 与 const,彻底搞懂作用域
  • 数据结构笔记4:数组、链表OJ
  • 华为云 Flexus+DeepSeek 征文|华为云 Flexus 云服务 Dify-LLM 平台深度部署指南:从基础搭建到高可用实践
  • 疏通经脉: Bridge 联通逻辑层和渲染层
  • 使用component封装组件和h函数的用法
  • 数据结构之Map和Set
  • 打造地基: App拉起基础小程序容器
  • linux面试常考
  • 正交视图三维重建 笔记 2d线到3d线
  • 使用deepseek制作“喝什么奶茶”随机抽签小网页
  • Jina-Embeddings-V4:多模态向量模型的革命性突破与实战指南
  • Python生成器表达式最佳实践指南:何时使用与高效选择
  • Flutter基础(控制器)
  • Python基础(吃洋葱小游戏)
  • LINUX628 NFS 多web;主从dns;ntp;samba