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
    就显得非常方便。

我该如何选择?

知识吐司
知识吐司

专注K12教育的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不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

778

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

684

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

769

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

739

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1445

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

571

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

579

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

751

2023.08.11

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

70

2026.01.23

热门下载

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

精品课程

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

共4课时 | 21.7万人学习

Django 教程
Django 教程

共28课时 | 3.5万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

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

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