0

0

Python怎么从pandas DataFrame中选择特定的行和列_pandas数据索引与切片技巧

冰火之心

冰火之心

发布时间:2025-09-14 08:32:01

|

598人浏览过

|

来源于php中文网

原创

答案:pandas中选择数据的核心方法是loc、iloc和布尔索引。loc基于标签进行索引,支持切片包含结束点,适合使用行索引和列名操作;iloc基于整数位置,切片行为与python列表一致,适用于按位置访问数据;布尔索引通过条件筛选行,可结合逻辑运算符实现复杂查询。优先使用loc保证代码可读性,按位置操作时用iloc,避免链式索引以防止settingwithcopywarning,复杂条件可用query()提升可读性,单值访问推荐at和iat提高效率。

python怎么从pandas dataframe中选择特定的行和列_pandas数据索引与切片技巧

在Pandas中,要从DataFrame中选择特定的行和列,核心方法主要有三种:基于标签的

loc
、基于整数位置的
iloc
,以及非常灵活的布尔索引。理解并熟练运用它们,能让你在数据处理时事半功倍,避免许多不必要的麻烦。

解决方案

Pandas DataFrame的数据索引与切片,就像你在地图上找具体位置一样,需要明确的坐标。我们通常会用到

loc
iloc
和布尔索引这三把“瑞士军刀”。

1. 使用

loc
进行基于标签的索引和切片

loc
是我个人最常用也最推荐的方法之一,因为它直接使用行索引(index)和列名(column names)来定位数据,非常直观。它的基本语法是
df.loc[row_label, column_label]

立即学习Python免费学习笔记(深入)”;

  • 选择单行或单列:

    import pandas as pd
    import numpy as np
    
    # 创建一个示例DataFrame
    data = {'A': [1, 2, 3, 4],
            'B': [5, 6, 7, 8],
            'C': [9, 10, 11, 12]}
    df = pd.DataFrame(data, index=['x', 'y', 'z', 'w'])
    print("原始DataFrame:\n", df)
    
    # 选择索引为'y'的行
    print("\n选择索引为'y'的行:\n", df.loc['y'])
    
    # 选择列'B'
    print("\n选择列'B':\n", df.loc[:, 'B'])
  • 选择多行或多列: 可以传入一个列表。

    # 选择索引为'x'和'z'的行
    print("\n选择索引为'x'和'z'的行:\n", df.loc[['x', 'z']])
    
    # 选择列'A'和'C'
    print("\n选择列'A'和'C':\n", df.loc[:, ['A', 'C']])
  • 选择行和列的组合:

    # 选择索引为'y'和'w'的行的列'A'和'C'
    print("\n选择索引为'y','w'的行的列'A','C':\n", df.loc[['y', 'w'], ['A', 'C']])
    
    # 选择从索引'y'到'w'(包含)的所有行,以及从列'A'到'C'(包含)的所有列
    # 注意:loc的切片是包含结束点的
    print("\n切片选择行'y'到'w',列'A'到'C':\n", df.loc['y':'w', 'A':'C'])

2. 使用

iloc
进行基于整数位置的索引和切片

iloc
则完全依赖于数据的整数位置,就像Python列表的索引一样。它的基本语法是
df.iloc[row_index, column_index]

  • 选择单行或单列:

    # 选择第1行(索引为0开始)
    print("\n选择第1行:\n", df.iloc[0])
    
    # 选择第2列(索引为0开始)
    print("\n选择第2列:\n", df.iloc[:, 1])
  • 选择多行或多列: 同样可以传入一个列表。

    # 选择第0和第2行
    print("\n选择第0和第2行:\n", df.iloc[[0, 2]])
    
    # 选择第0和第2列
    print("\n选择第0和第2列:\n", df.iloc[:, [0, 2]])
  • 选择行和列的组合:

    # 选择第1和第3行的第0和第2列
    print("\n选择第1和第3行的第0和第2列:\n", df.iloc[[1, 3], [0, 2]])
    
    # 切片选择从第1行到第3行(不包含第3行),以及从第0列到第2列(不包含第2列)
    # 注意:iloc的切片是排他性的,与Python列表切片行为一致
    print("\n切片选择行1到3(不含3),列0到2(不含2):\n", df.iloc[1:3, 0:2])

3. 使用布尔索引进行条件筛选

布尔索引是我在进行数据清洗和分析时最常用的功能之一,它允许你根据一个或多个条件来选择行。

  • 单条件筛选:

    # 选择列'A'中值大于2的所有行
    print("\n选择列'A'中值大于2的所有行:\n", df[df['A'] > 2])
  • 多条件筛选: 使用

    &
    (AND),
    |
    (OR),
    ~
    (NOT) 运算符,并且每个条件表达式必须用括号括起来。

    # 选择列'A'大于2且列'B'小于8的所有行
    print("\n选择列'A'>2且'B'<8的所有行:\n", df[(df['A'] > 2) & (df['B'] < 8)])
    
    # 选择列'A'等于1或列'C'大于11的所有行
    print("\n选择列'A'==1或'C'>11的所有行:\n", df[(df['A'] == 1) | (df['C'] > 11)])
    
    # 选择列'A'不等于1的所有行
    print("\n选择列'A'不等于1的所有行:\n", df[~(df['A'] == 1)])
  • 结合

    loc
    进行布尔索引和列选择:

    # 选择列'A'大于2的所有行的列'B'和'C'
    print("\n选择列'A'>2的所有行的列'B'和'C':\n", df.loc[df['A'] > 2, ['B', 'C']])

在Pandas中,
loc
iloc
究竟有何区别,我该如何选择?

这确实是初学者,甚至是一些有经验的用户也时常会混淆的地方。说实话,刚开始用的时候我也常常搞不清楚什么时候该用哪个。但核心的区别其实非常简单:

loc
是基于标签(label)的,而
iloc
是基于整数位置(integer location)的。

想象一下你有一本书,

loc
就像你在目录里找“第三章”或者“附录A”一样,它关心的是章节的名字。而
iloc
则像你在书架上数“从上往下第三本书”或者“从左往右第五页”,它关心的是物理上的顺序。

loc
的特点:

  • 使用行索引和列名。 如果你的DataFrame有自定义的行索引(比如日期、ID、类别名称),或者你希望用明确的列名来操作,
    loc
    是你的首选。
  • 切片是包含结束点的。 这一点非常关键,也是和Python原生切片行为不同的地方。比如
    df.loc['start_label':'end_label']
    会包含
    end_label
    对应的行或列。这在处理时间序列数据或者有明确范围的数据时非常方便。
  • 可以进行布尔索引。 结合条件筛选时,
    loc
    能让你在筛选行的同时,也指定要查看哪些列,这比单独的布尔索引更强大和灵活。

iloc
的特点:

  • 使用从0开始的整数位置。 它不关心你的行索引或列名是什么,只关心它们在DataFrame中的排列顺序。
  • 切片是排他性的。 比如
    df.iloc[0:5]
    会选择索引为0到4的行,不包含第5行。这和Python列表的切片行为完全一致,对于熟悉Python的人来说更容易理解。
  • 适合循环或需要按位置动态选择数据时。 当你需要遍历DataFrame的特定部分,或者你的选择逻辑是基于数据在DataFrame中的物理位置时,
    iloc
    就显得非常方便。

我该如何选择?

Zyro AI Image Upscaler
Zyro AI Image Upscaler

Zyro出品的AI图片放大工具

下载

我的建议是:

  1. 优先使用
    loc
    如果你的DataFrame有有意义的行索引和列名,并且你的操作是基于这些标签的,那么
    loc
    能让你的代码更具可读性和健壮性。即使数据的顺序发生变化,只要标签不变,你的代码依然能正确工作。
  2. 当需要按位置操作时使用
    iloc
    比如,你总是想获取DataFrame的第一行,或者最后一列,而不管它们的标签是什么。或者在某些算法中,你需要基于数据的相对位置进行切片。
  3. 避免混合使用。 尽量保持代码风格的一致性,减少混淆。

一个常见的错误就是把

loc
的切片行为(包含结束)和
iloc
的切片行为(不包含结束)搞混。我个人在写代码的时候,如果涉及到切片,会特别留意当前用的是
loc
还是
iloc
,避免因为这个小细节导致数据选择错误。

如何利用布尔索引进行复杂的数据筛选,有哪些常见陷阱?

布尔索引是Pandas数据筛选的利器,它允许你根据数据的实际值来动态选择行,这在数据分析和清洗中几乎是无处不在的。

利用布尔索引进行复杂筛选:

  • 多条件组合: 如前面所示,使用

    &
    (AND),
    |
    (OR),
    ~
    (NOT) 运算符可以组合多个条件。例如,如果你想找出年龄在18到30岁之间,并且是女性的用户数据:

    # 假设df有一个'Age'和'Gender'列
    # df[(df['Age'] >= 18) & (df['Age'] <= 30) & (df['Gender'] == 'Female')]

    这里的关键是每个独立的条件表达式都必须用括号

    ()
    括起来,因为Python的位运算符(
    &
    ,
    |
    )优先级高于比较运算符(
    >
    ,
    <
    ,
    ==
    等)。如果没有括号,可能会导致意想不到的错误。

  • 使用

    isin()
    方法: 当你想选择某一列的值在某个特定列表中的所有行时,
    isin()
    方法非常方便。

    # 选择列'City'是'New York'或'London'的行
    # df[df['City'].isin(['New York', 'London'])]

    这比写

    (df['City'] == 'New York') | (df['City'] == 'London')
    要简洁得多,尤其当列表很长时。

  • 使用

    str.contains()
    进行字符串匹配: 如果你的列是字符串类型,并且你需要根据子字符串匹配来筛选,
    str.contains()
    是一个很好的选择。

    # 选择列'Description'中包含'error'关键词的行
    # df[df['Description'].str.contains('error', na=False)]

    na=False
    参数很重要,它指定了如何处理NaN值。如果为
    True
    ,则NaN值也会被视为包含(或不包含,取决于具体实现),通常我们希望它们不匹配。

常见陷阱:

  1. 忘记括号: 这是最常见的错误,没有之一。

    # 错误示例:
    # df[df['A'] > 2 & df['B'] < 8]
    # 这会先计算 2 & df['B'],然后用 df['A'] > (结果)
    # 正确写法:
    # df[(df['A'] > 2) & (df['B'] < 8)]

    Pandas会告诉你一个

    ValueError: The truth value of a Series is ambiguous
    ,或者直接得到错误的结果。

  2. 处理

    NaN
    值: 当你的条件列中包含
    NaN
    (Not a Number)时,布尔运算可能会产生意外结果。
    NaN
    与任何值(包括它自己)的比较结果都是
    False

    # 假设df有一个包含NaN的'Value'列
    # df[df['Value'] > 10]
    # 结果会排除所有NaN的行,即使你可能希望它们被包含在内或单独处理。

    处理

    NaN
    的常见方法是:

    • dropna()
      在筛选前先删除包含
      NaN
      的行。
    • fillna()
      在筛选前先用某个值填充
      NaN
    • isna()
      /
      notna()
      专门用来检查
      NaN
      值。
      # 选择'Value'列不是NaN的行
      # df[df['Value'].notna()]
  3. 对Series进行布尔运算时,Series的索引必须对齐。 如果你创建了一个布尔Series,它的索引与DataFrame的索引不匹配,Pandas会尝试对齐,如果对齐失败(例如,索引标签不完全一致),可能会填充

    NaN
    ,然后导致错误或意外结果。通常,我们直接在DataFrame内部生成布尔Series,所以这个问题不常遇到,但了解其原理有助于调试。

布尔索引的强大之处在于它的灵活性,但这种灵活性也要求我们对数据类型和运算符优先级有清晰的认识。我通常会把复杂的条件分解成小的、可测试的部分,确保每个布尔Series都按预期生成,然后再组合起来。

除了基础索引,还有哪些高级技巧能提升我的数据选择效率?

在掌握了

loc
iloc
和布尔索引这些基础之后,还有一些高级技巧和最佳实践可以进一步提升你在Pandas中选择数据的效率和代码的可读性,同时避免一些常见的性能陷阱。

  1. 避免链式索引 (Chained Indexing) 写入操作,警惕

    SettingWithCopyWarning
    这是Pandas用户经常遇到的一个“坑”。当你像这样操作时:

    # df[df['col_A'] > 5]['col_B'] = 10 # 错误或产生警告

    你可能会遇到

    SettingWithCopyWarning
    。这是因为
    df[df['col_A'] > 5]
    返回的可能是一个“视图”(view)而不是一个“副本”(copy)。当你试图修改一个视图时,修改可能不会反映到原始DataFrame上,或者即使反映了,Pandas也会发出警告,因为它不确定你的意图。

    正确且推荐的做法是使用

    loc
    iloc

    # 修改满足条件的行的特定列
    df.loc[df['col_A'] > 5, 'col_B'] = 10

    这种方式明确地告诉Pandas,你打算在原始DataFrame上进行修改,它会返回一个指向原始数据的引用,确保修改生效。

  2. 使用

    query()
    进行字符串表达式筛选: 对于复杂的布尔条件筛选,特别是当条件涉及多个列时,
    query()
    方法能让你的代码更像SQL语句,可读性大大提高。它接受一个字符串表达式。

    # 假设df有'Age', 'Gender', 'Score'列
    # df.query('Age > 25 and Gender == "Male" and Score > 80')

    query()
    内部会进行优化,在某些情况下,它的性能可能比直接的布尔索引更好,因为它避免了创建多个中间的布尔Series。它也支持使用
    @
    符号引用外部变量:

    min_age = 25
    # df.query('Age > @min_age')
  3. 使用

    filter()
    进行列的筛选: 如果你需要根据列名的一部分、正则表达式或者一个列表来选择列,
    filter()
    方法非常有用。

    # 选择列名中包含'A'的列
    # df.filter(like='A')
    
    # 选择列名以'C'开头的列
    # df.filter(regex='^C')
    
    # 选择特定列(与df[['col1', 'col2']]类似,但更灵活)
    # df.filter(items=['col1', 'col2'])

    这在处理大量列或者需要动态选择列时非常方便。

  4. at
    iat
    用于快速单值访问:
    当你知道确切的行标签/位置和列名/位置,并且只需要访问或修改单个单元格时,
    at
    iat
    loc
    iloc
    效率更高。它们是针对单点访问进行了优化的。

    # 获取索引为'y',列为'A'的值
    # value = df.at['y', 'A']
    
    # 修改索引为'z',列为'C'的值
    # df.at['z', 'C'] = 100
    
    # 获取第1行,第0列的值
    # value = df.iat[1, 0]

    虽然这看起来是微小的优化,但在大型数据集上进行大量单点操作时,累积起来的性能提升会很显著。

这些高级技巧并非每次数据选择都必须使用,但它们提供了更高效、更具可读性或更安全的选择。在实际工作中,我通常会根据具体场景和数据规模来决定使用哪种方法。例如,对于简单的筛选,直接布尔索引就足够了;但如果条件复杂或者需要避免

SettingWithCopyWarning
loc
query()
就是更好的选择。理解这些工具的适用场景,能让你在数据处理的道路上走得更远。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

1133

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

381

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2132

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

380

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

1663

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

585

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

440

2024.04.29

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

4

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号