jjzjj

Pandas数据选取中df[]、df.loc[]、df.iloc[]、df.at[]、df.iat[]的区别及用法

金戈鐡馬 2023-12-18 原文

1、引言

  Pandas是作为Python数据分析著名的工具包,提供了多种数据选取的方法,方便实用。本文主要介绍Pandas的几种数据选取的方法。

  Pandas中,数据主要保存为Dataframe和Series是数据结构,这两种数据结构数据选取的方式基本一致,本文主要以Dataframe为例进行介绍。

  在Dataframe中选取数据大抵包括3中情况:

  1)行(列)选取(单维度选取):df[]。这种情况一次只能选取行或者列,即一次选取中,只能为行或者列设置筛选条件(只能为一个维度设置筛选条件)。

  2)区域选取(多维选取):df.loc[],df.iloc[]。这种方式可以同时为多个维度设置筛选条件。

  3)单元格选取(点选取):df.at[],df.iat[]。准确定位一个单元格。

  接下来,我们以下面的数据为例,分别通过实例介绍这三种情况。

import pandas as pd
import numpy as np

data = {'name': ['Joe', 'Mike', 'Jack', 'Rose', 'David', 'Marry', 'Wansi', 'Sidy', 'Jason', 'Even'],

    'age': [25, 32, 18, np.nan, 15, 20, 41, np.nan, 37, 32],

    'gender': [1, 0, 1, 1, 0, 1, 0, 0, 1, 0],

    'isMarried': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}

labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

df = pd.DataFrame(data, index=labels)

df
    name   age  gender isMarried
a    Joe  25.0       1       yes
b   Mike  32.0       0       yes
c   Jack  18.0       1        no
d   Rose   NaN       1       yes
e  David  15.0       0        no
f  Marry  20.0       1        no
g  Wansi  41.0       0        no
h   Sidy   NaN       0       yes
i  Jason  37.0       1        no
j   Even  32.0       0        no

2、行(列)选取:df[]

  行(列)选取是在单一维度上进行数据的选取,即以行为单位进行选取或者以列为单位进行选取。Dataframe对象的行有索引(index),默认情况下是[0,1,2,……]的整数序列,也可以自定义添加另外的索引,例如上面的labels,(为区分默认索引和自定义的索引,在本文中将默认索引称为整数索引,自定义索引称为标签索引)。Dataframe对象的每一列都有列名,可以通过列名实现对列的选取。

  1)选取行

选取行的方式包括三种:整数索引切片、标签索引切片和布尔数组。

  a)整数索引切片:前闭后开

  • 选取第一行:

df[0:1]
  name   age  gender isMarried
a  Joe  25.0       1       yes
  • 选取前两行:

df[0:2]
   name   age  gender isMarried
a   Joe  25.0       1       yes
b  Mike  32.0       0       yes

  b)标签索引切片:前闭后闭

  • 选取第一行:

df[:'a']
  name   age  gender isMarried
a  Joe  25.0       1       yes
  • 选取前两行:

df['a':'b']
   name   age  gender isMarried
a   Joe  25.0       1       yes
b  Mike  32.0       0       yes

  注意:整数索引切片是前闭后开,标签索引切片是前闭后闭,这点尤其要注意。

  c)布尔数组

  • 选取前三行

df[[True,True,True,False,False,False,False,False,False,False]]
   name   age  gender isMarried
a   Joe  25.0       1       yes
b  Mike  32.0       0       yes
c  Jack  18.0       1        no
  • 选取所有age大于30的行

df[[each>30 for each in df['age']]]
    name   age  gender isMarried
b   Mike  32.0       0       yes
g  Wansi  41.0       0        no
i  Jason  37.0       1        no
j   Even  32.0       0        no

  通过布尔数组的方式,又可以衍生出下面的选取方式:

  • 选取所有age大于30的行

df[df['age']>30]
    name   age  gender isMarried
b   Mike  32.0       0       yes
g  Wansi  41.0       0        no
i  Jason  37.0       1        no
j   Even  32.0       0        no
  • 选取出所有age大于30,且isMarried为no的行

df[(df['age']>30) & (df['isMarried']=='no')]
    name   age  gender isMarried
g  Wansi  41.0       0        no
i  Jason  37.0       1        no
j   Even  32.0       0        no
  • 选取出所有age为20或32的行

df[(df['age']==20) | (df['age']==32)]
    name   age  gender isMarried
b   Mike  32.0       0       yes
f  Marry  20.0       1        no
j   Even  32.0       0        no

  注意:像上面这种通过多个布尔条件判断的情况,多个条件最好(一定)用括号括起来,否则非常容易出错。

  2)列选取

  列选取方式也有三种:标签索引、标签列表、Callable对象

  a)标签索引:选取单个列

  • 选取name列所有数据

df['name']
a      Joe
b     Mike
c     Jack
d     Rose
e    David
f    Marry
g    Wansi
h     Sidy
i    Jason
j     Even
Name: name, dtype: object

  b)标签列表:选取多个列

  • 选取name和age两列数据

df[['name','age']]
    name   age
a    Joe  25.0
b   Mike  32.0
c   Jack  18.0
d   Rose   NaN
e  David  15.0
f  Marry  20.0
g  Wansi  41.0
h   Sidy   NaN
i  Jason  37.0
j   Even  32.0

  c)callable对象

  • 选取第一列

df[lambda df: df.columns[0]]
a      Joe
b     Mike
c     Jack
d     Rose
e    David
f    Marry
g    Wansi
h     Sidy
i    Jason
j     Even
Name: name, dtype: object

3、区域选取

  区域选取可以从多个维度(行和列)对数据进行筛选,可以通过df.loc[],df.iloc[],df.ix[]三种方法实现。采用df.loc[],df.iloc[],df.ix[]这三种方法进行数据选取时,方括号内必须有两个参数,第一个参数是对行的筛选条件,第二个参数是对列的筛选条件,两个参数用逗号隔开。df.loc[],df.iloc[],df.ix[]的区别如下:

  df.loc[]只能使用标签索引,不能使用整数索引,通过便签索引切边进行筛选时,前闭后闭。

  df.iloc[]只能使用整数索引,不能使用标签索引,通过整数索引切边进行筛选时,前闭后开。;

  df.ix[]既可以使用标签索引,也可以使用整数索引。

  下面分别通过实例演示这三种方法。

3.1 df.loc[]

  1)对行进行选取

  • 选取索引为‘a’的行:

df.loc['a', :]
name          Joe
age          25.0
gender          1
isMarried     yes
Name: a, dtype: object
  • 选取索引为‘a’或‘b’或‘c’的行

df.loc[['a','b','c'], :]
   name   age  gender isMarried
a   Joe  25.0       1       yes
b  Mike  32.0       0       yes
c  Jack  18.0       1        no
  • 选取从‘a’到‘d’的所有行(包括‘d’行)

df.loc['a':'d', :]
   name   age  gender isMarried
a   Joe  25.0       1       yes
b  Mike  32.0       0       yes
c  Jack  18.0       1        no
d  Rose   NaN       1       yes
  • 选取所有age大于30的行

df.loc[df['age']>30,:]
    name   age  gender isMarried
b   Mike  32.0       0       yes
g  Wansi  41.0       0        no
i  Jason  37.0       1        no
j   Even  32.0       0        no

也可以使用下面两方法:

方法一:

df.loc[df.loc[:,'age']>30, :]
   name   age  gender isMarried
b   Mike  32.0       0       yes
g  Wansi  41.0       0        no
i  Jason  37.0       1        no
j   Even  32.0       0        no

方法二:

df.loc[df.iloc[:,1]>30, :]
    name   age  gender isMarried
b   Mike  32.0       0       yes
g  Wansi  41.0       0        no
i  Jason  37.0       1        no
j   Even  32.0       0        no
  • 用callable对象选取age大于30的所有行

df.loc[lambda df:df['age'] > 30, :]
    name   age  gender isMarried
b   Mike  32.0       0       yes
g  Wansi  41.0       0        no
i  Jason  37.0       1        no
j   Even  32.0       0        no

  2)对列选取

  • 输出所有人的姓名(选取name列)

df.loc[:, 'name']
a      Joe
b     Mike
c     Jack
d     Rose
e    David
f    Marry
g    Wansi
h     Sidy
i    Jason
j     Even
Name: name, dtype: object
  • 输出所有人的姓名和年龄(选取name和age列)

df.loc[:, 'name':'age']
    name   age
a    Joe  25.0
b   Mike  32.0
c   Jack  18.0
d   Rose   NaN
e  David  15.0
f  Marry  20.0
g  Wansi  41.0
h   Sidy   NaN
i  Jason  37.0
j   Even  32.0
  • 输出所有人的姓名、年龄、婚否(选取name、age、isMarried列)

df.loc[:, ['name','age','isMarried']]
    name   age isMarried
a    Joe  25.0       yes
b   Mike  32.0       yes
c   Jack  18.0        no
d   Rose   NaN       yes
e  David  15.0        no
f  Marry  20.0        no
g  Wansi  41.0        no
h   Sidy   NaN       yes
i  Jason  37.0        no
j   Even  32.0        no
  • 用布尔数组的方式选取前3列

df.loc[:, [True,True,True,False]]
    name   age  gender
a    Joe  25.0       1
b   Mike  32.0       0
c   Jack  18.0       1
d   Rose   NaN       1
e  David  15.0       0
f  Marry  20.0       1
g  Wansi  41.0       0
h   Sidy   NaN       0
i  Jason  37.0       1
j   Even  32.0       0

  3)同时对行和列进行筛选

  • 输出年龄大于30的人的姓名和年龄

df.loc[df['age']>30,['name','age']]
    name   age
b   Mike  32.0
g  Wansi  41.0
i  Jason  37.0
j   Even  32.0
  • 输出行名为‘Mike’或‘Marry’的姓名和年龄

df.loc[(df['name']=='Mike') |(df['name']=='Marry'),['name','age']]
    name   age
b   Mike  32.0
f  Marry  20.0

3.2 df.iloc[]

  1)行选取

  • 选取第2行

df.iloc[1, :]
name         Mike
age          32.0
gender          0
isMarried     yes
Name: b, dtype: object
  • 选取前3行

df.iloc[:3, :]
   name   age  gender isMarried
a   Joe  25.0       1       yes
b  Mike  32.0       0       yes
c  Jack  18.0       1        no
  • 选取第2行、第4行、第6行

df.iloc[[1,3,5],:]
    name   age  gender isMarried
b   Mike  32.0       0       yes
d   Rose   NaN       1       yes
f  Marry  20.0       1        no

  2)列选取

  • 选取第2列

df.iloc[:, 1]
a    25.0
b    32.0
c    18.0
d     NaN
e    15.0
f    20.0
g    41.0
h     NaN
i    37.0
j    32.0
Name: age, dtype: float64
  • 选取前3列

df.iloc[:, 0:3]
    name   age  gender
a    Joe  25.0       1
b   Mike  32.0       0
c   Jack  18.0       1
d   Rose   NaN       1
e  David  15.0       0
f  Marry  20.0       1
g  Wansi  41.0       0
h   Sidy   NaN       0
i  Jason  37.0       1
j   Even  32.0       0
  • 选取第1列、第3列和第4列

df.iloc[:, [0,2,3]]
    name  gender isMarried
a    Joe       1       yes
b   Mike       0       yes
c   Jack       1        no
d   Rose       1       yes
e  David       0        no
f  Marry       1        no
g  Wansi       0        no
h   Sidy       0       yes
i  Jason       1        no
j   Even       0        no
  • 通过布尔数组选取前3列

df.iloc[:,[True,True,True,False]]
    name   age  gender
a    Joe  25.0       1
b   Mike  32.0       0
c   Jack  18.0       1
d   Rose   NaN       1
e  David  15.0       0
f  Marry  20.0       1
g  Wansi  41.0       0
h   Sidy   NaN       0
i  Jason  37.0       1
j   Even  32.0       0

  3)同时选取行和列

  • 选取第2行的第1列、第3列、第4列

df.iloc[1, [0,2,3]]
name         Mike
gender          0
isMarried     yes
Name: b, dtype: object
  • 选取前3行的前3列

df.iloc[:3, :3]
   name   age  gender
a   Joe  25.0       1
b  Mike  32.0       0
c  Jack  18.0       1

4 单元格选取

  单元格选取包括df.at[]和df.iat[]两种方法。df.at[]和df.iat[]使用时必须输入两个参数,即行索引和列索引,其中df.at[]只能使用标签索引,df.iat[]只能使用整数索引。df.at[]和df.iat[]选取的都是单个单元格(单行单列),所以返回值都为基本数据类型。

4.1 df.at[]

  • 选取b行的name列

df.at['b','name']
Mike

4.2 df.iat[]

  • 选取第2行第1列

df.iat[1,0]
Mike

5 拓展与总结

  1)选取某一整行(多个整行)或某一整列(多个整列)数据时,可以用df[]、df.loc[]、df.iloc[],此时df[]的方法书写要简单一些。

  2)进行区域选取时,如果只能用标签索引,则使用df.loc[],如果只能用整数索引,则用df.iloc[]。df.loc[]既能查询,又能覆盖写入,强烈推荐使用!

  3)如果选取单元格,则df.at[]、df.iat[]、df.loc[]、df.iloc[]都可以,不过要注意参数。  

  4)选取数据时,返回值存在以下情况:

  • 如果返回值包括单行多列或多行单列时,返回值为Series对象;

  • 如果返回值包括多行多列时,返回值为DataFrame对象;

  • 如果返回值仅为一个单元格(单行单列)时,返回值为基本数据类型,例如str,int等。

  5)df[]的方式只能选取行和列数据,不能精确到单元格,所以df[]的返回值一定DataFrame或Series对象。

  6)当使用DataFrame的默认索引(整数索引)时,整数索引即为标签索引。例如,使用上面的data实例化一个DataFrame对象:

df2 = pd.DataFrame(data)
df2.loc[1,'name']
Mike
df2.iloc[1,0]
Mike

有关Pandas数据选取中df[]、df.loc[]、df.iloc[]、df.at[]、df.iat[]的区别及用法的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  4. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  5. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  6. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  7. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  8. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  9. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  10. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

随机推荐