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

答案: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 pdimport numpy as np# 创建一个示例DataFramedata = {'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' 2) & (df['B'] 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

    就显得非常方便。

我该如何选择?

Whimsical

Whimsical

Whimsical推出的AI思维导图工具

Whimsical 182

查看详情 Whimsical

我的建议是:

  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) &amp; (df['Age'] <= 30) &amp; (df['Gender'] == 'Female')]

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

    ()

    括起来,因为Python的位运算符(

    &amp;

    ,

    |

    )优先级高于比较运算符(

    >

    ,

    <

    ,

    ==

    等)。如果没有括号,可能会导致意想不到的错误。

  • 使用

    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 &amp; df['B']  (结果)# 正确写法:# df[(df['A'] > 2) &amp; (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()

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

以上就是Python怎么从pandas DataFrame中选择特定的行和列_pandas数据索引与切片技巧的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1371567.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月14日 11:34:04
下一篇 2025年12月12日 21:56:10

相关推荐

  • python如何进行sha256或md5加密_python hashlib模块实现sha256和md5加密

    Python中使用hashlib模块进行SHA256或MD5哈希计算,需先将字符串encode为字节,再调用相应算法的update()和hexdigest()方法;MD5因存在碰撞漏洞不推荐用于安全场景,SHA256更安全且广泛用于密码存储、数字签名等;但仅用SHA256仍不足,应对敏感数据加盐(s…

    2025年12月14日
    000
  • python中defaultdict怎么使用?

    defaultdict是dict的子类,访问不存在的键时自动创建默认值,避免KeyError。它通过指定工厂函数(如int、list、set或lambda)生成默认值,常用于计数、分组和构建复杂数据结构。相比普通dict的get()或if/else,defaultdict代码更简洁,尤其适合累加和追…

    2025年12月14日
    000
  • python中怎么对字典按键进行排序?

    答案:Python中对字典按键排序需使用sorted()函数获取有序视图,因字典本身不支持直接排序以保持哈希表的高效性。1. 可通过sorted(my_dict.keys())获得排序后的键列表,再遍历原字典;2. 使用sorted(my_dict.items())得到按键排序的键值对元组列表;3.…

    2025年12月14日
    000
  • Python怎么检查一个文件是否存在_Python文件存在性检查方法

    检查文件是否存在最直接的方法是使用os.path.exists(),而更现代的方式是使用pathlib模块的Path.exists()方法。两种方式均可判断路径是否存在,但pathlib提供更直观、面向对象的API,支持链式调用和跨平台兼容,推荐用于复杂路径操作。 Python要检查一个文件是否存在…

    2025年12月14日
    000
  • Python while 循环中输入处理与类型比较的常见陷阱及解决方案

    本文深入探讨了Python while 循环在处理用户输入时可能遇到的常见问题,包括循环控制逻辑、数据类型转换与比较错误。通过分析一个具体的代码案例,我们将详细讲解如何正确使用 break 和 continue 语句,以及如何避免整数与字符串之间不匹配的比较,从而构建健壮的用户交互程序。 1. 理解…

    2025年12月14日
    000
  • PyTorch模型在无PyTorch环境下的部署:利用ONNX实现跨平台推理

    本文旨在解决PyTorch模型在不包含PyTorch依赖的生产环境中部署的挑战。通过将训练好的PyTorch模型导出为开放神经网络交换(ONNX)格式,开发者可以在各种支持ONNX的运行时(如ONNX Runtime)中进行高效推理,从而摆脱对PyTorch框架的直接依赖,实现模型的轻量级、跨平台部…

    2025年12月14日
    000
  • Tkinter游戏开发实战:打造“寻找钻石”游戏并避免常见陷阱

    本文将引导读者使用Python的Tkinter库构建一个名为“寻找钻石”的简单GUI游戏。教程涵盖Tkinter窗口、按钮创建与布局、事件处理、游戏逻辑实现以及消息框交互。特别强调了在事件绑定中因函数名大小写错误导致程序无法运行的常见陷阱,并提供了有效的调试策略和代码优化建议,旨在提升Tkinter…

    2025年12月14日
    000
  • Abjad中交叉音符(Dead Notes)的正确实现方法

    本教程详细介绍了如何在Abjad中正确创建交叉音符(Dead Notes)。针对常见的xNote函数引发的LilyPondParser错误,我们将阐明其根源,并指导读者使用LilyPond原生且正确的xNotesOn和xNotesOff指令。通过示例代码,读者将学会如何在Abjad脚本中无缝集成这些…

    2025年12月14日
    000
  • Python教程:从JSON数据中精确移除浮点NaN值

    本教程详细讲解如何使用Python高效地从JSON数据结构中识别并移除浮点型NaN(非数字)值。通过利用math.isnan()函数和字典推导式,文章提供了一种专业且易于理解的数据清洗方案,旨在区分NaN与null,确保数据准确性,并附有完整的代码示例和关键注意事项,帮助开发者优化数据处理流程。 引…

    2025年12月14日
    000
  • 将一维数组重塑为接近正方形的二维数组

    本文旨在解决将一维 NumPy 数组重塑为尽可能接近正方形的二维数组的问题。由于并非所有数字都能完美分解为两个相等的整数,因此我们需要找到两个因子,它们的乘积等于数组的长度,并且尽可能接近。本文将提供几种实现此目的的方法,包括快速方法和更全面的方法,并提供代码示例。 问题背景 在数据处理和科学计算中…

    2025年12月14日
    000
  • python如何实现一个上下文管理器_python with语句上下文管理器的实现方法

    上下文管理器通过__enter__和__exit__方法确保资源正确获取与释放,如文件操作中自动关闭文件;使用with语句可优雅管理资源,即使发生异常也能保证清理逻辑执行;通过contextlib.contextmanager装饰器可用生成器函数简化实现;支持数据库连接、线程锁等场景,并能嵌套管理多…

    2025年12月14日
    000
  • 将一维数组重塑为接近正方形的矩阵

    本文探讨了如何将一维 NumPy 数组重塑为尽可能接近正方形的二维矩阵,即找到两个因子 p 和 q,使得 p * q 等于数组长度 n,且 p 尽可能接近 sqrt(n)。文章提供了两种实现方法:一种是速度更快的简单方法,适用于较小的 n;另一种是更通用的方法,基于质因数分解和幂集搜索,适用于更复杂…

    2025年12月14日
    000
  • python中怎么在循环中获取索引?

    最简洁的方式是使用enumerate()函数,它能同时获取索引和值,代码更清晰高效。 enumerate(my_list)返回索引-值对,支持start参数自定义起始索引,可与zip()等结合处理多序列,适用于任意可迭代对象,内存效率高,尤其适合大型数据集。相比range(len()),enumer…

    2025年12月14日
    000
  • Pandas Series 字符串处理:分割、修改首部并连接

    本文介绍了如何使用 Pandas 对包含城市和区域名称的 Series 进行字符串处理,实现在城市名称后添加 “_sub” 后缀,同时保留区域信息。文章将详细讲解如何利用正则表达式进行替换,避免传统分割和连接方法可能导致的问题,并提供清晰的代码示例和解释。 在 Pandas …

    2025年12月14日
    000
  • Python怎么反转一个列表_Python列表反转操作方法

    反转Python列表有三种主要方法:1. 使用reverse()方法直接修改原列表;2. 使用切片[::-1]创建新列表,不改变原列表;3. 使用reversed()函数返回迭代器,需转换为列表。 反转Python列表,其实就是把列表元素顺序颠倒过来。方法不少,直接用内置函数或者切片操作都挺方便的。…

    2025年12月14日
    000
  • Python怎么读取CSV文件_Python CSV文件读取方法详解

    Python读取CSV文件主要有两种方式:使用内置csv模块适合简单逐行处理,内存占用低;而pandas的read_csv()则将数据直接加载为DataFrame,便于数据分析。csv.reader按列表形式读取,适用于已知列顺序的场景;csv.DictReader以字典形式读取,通过列名访问更直观…

    2025年12月14日 好文分享
    000
  • Python怎么配置日志(logging)_Python logging模块配置与使用

    答案:Python日志配置通过logger、handler和formatter实现,logger设置级别并记录日志,handler定义日志输出位置,formatter指定日志格式;可通过dictConfig将配置集中管理,多模块使用同名logger可共享配置,主程序需先初始化logging。 Pyt…

    2025年12月14日
    000
  • Pandas Series字符串处理:使用正则表达式实现灵活的前缀修改

    本文探讨了如何在Pandas Series中对字符串进行有条件的前缀修改,特别是为城市名称添加后缀,同时保留可能存在的区域信息。针对传统split-apply-join方法的局限性,文章重点介绍了一种高效且优雅的解决方案:利用Series.str.replace()结合正则表达式,通过一个简洁的模式…

    2025年12月14日
    000
  • Python怎么注释多行代码_Python多行注释方法汇总

    Python中实现多行注释主要靠三重引号字符串或连续#号。三重引号字符串未赋值时被忽略,常用于临时注释或文档说明,但仅当位于模块、类、函数开头时才被视为Docstring,成为可编程访问的__doc__属性;而普通多行注释应使用#,适合禁用代码或添加旁注。选择策略:对外接口用Docstring,调试…

    2025年12月14日
    000
  • python中lambda函数怎么使用_Python lambda匿名函数用法详解

    lambda函数是匿名函数,因无显式名称且可直接在需要函数处定义使用,常用于简化代码,如与map、filter、sorted等结合;其仅支持单表达式,适合简单逻辑,而复杂功能应使用def定义的函数以提升可读性。 lambda函数本质上是一种简洁的、单行的匿名函数,它允许你在需要函数的地方快速定义一个…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信