pandas中loc-iloc-ix的使用

Pandas中loc,iloc,ix的使用

使用 iloc 从DataFrame中筛选数据

iloc 是基于“位置”的Dataframe的操作,即主要基于下标的操作

简单使用

Pandas中的 iloc 是用基于整数的下标来进行数据定位/选择
iloc 的语法是 data.iloc[<row selection>, <column selection>], iloc 在Pandas中是用来通过数字来选择数据中具体的某些行和列。你可以设想每一行都有一个对应的下标(0,1,2,...),通过 iloc 我们可以利用这些下标去选择相应的行数据。同理,对于行也一样,想象每一列也有对应的下标(0,1,2,...),通过这些下标也可以选择相应的列数据。

在iloc中一共有 2 个 “参数” -行选择器-列选择器,例如:

    # 使用DataFrame 和 iloc 进行单行/列的选择
    # 行选择:
    data.iloc[0] # 数据中的第一行
    data.iloc[1] # 数据中的第二行
    data.iloc[-1] # 数据中的最后一行
    
    # 列选择:
    data.iloc[:, 0] # 数据中的第一列
    data.iloc[:, 1] # 数据中的第二列
    data.iloc[:, -1] # 数据中的最后一列 

行列混合选择

iloc 同样可以进行和列的混合选择,例如:

    # 使用 iloc 进行行列混合选择
    data.iloc[0:5] # 数据中的第 1-5 行
    data.iloc[:, 0:2] # 选择数据中的前2列和所有行
    data.iloc[[0, 3, 6, 24], [0, 5, 6]] # 选择第 1,4,7,25行 和 第 1,6,7 列
    data.iloc[0:5, 5:8] # 选择第1-6行 和 6-9列

使用 iloc 注意以下两点:

  • 如果使用iloc只选择了单独的一行会返回 Series 类型,而如果选择了多行数据则会返回 DataFrame 类型,如果你只选择了一行,但如果想要返回 DataFrame 类型可以传入一个单值list,具体例子看图:

    image

  • 当你使用 [1:5] 这种语法对数据进行切片的时候,要注意只选择了 1,2,3,44 个下标,而 5 并没有被包括进去,即使用[x:y]选择了下标从 xy-1 的数据

实际工作中,其实很少用到 iloc ,除非你想选择第一行( data.iloc[0] ) 或者 最后一行( data.iloc[-1] )

使用 loc 从DataFrame中筛选数据

可以在以下2中情况下使用 ioc

  • 使用 基于标签(列头)的下标的 查找
  • 使用 boolean / 有条件的 查找

使用 loc 的语法和 iloc 一样:data.loc[<row selection>, <column selection>]

使用基于标签(列头)的下标数据选择

使用 loc 进行数据选择是基于下标的(如果有的话),可以使用 df.set_index() 来设置下标, loc 方法直接通过下标来选择行。
例如将"last_name"这一列设置为下标:

    data.set_index("last_name", inplace=True)

效果如图:


image

现在我们已经将下标设置为"last_name",这样我们就可以根据"last_name"选择不同的数据了,使用 data.loc[<label>]

同样的可以查找单个值或者多个值,例子如图:


image

注意,第一个样例代码返回的是 Series 类型,而第二个样例代码返回的是 DataFrame 类型,同样你也可以通过传递一个单值list来返回一个 DataFrame 类型的数据

当然也可以使用 loc 对列进行选择,同时可以选择对列使用 " : "进行切片选择,效果如图:

image

同时,你还可以使用 " : " 对下标进行切片选择,例如 data.loc['Bruch':'Julio'] 会选择从下标为'Bruch'到下标为'Julio' 的所有行,例如:

    # 选择下标值为'Andrade' 和 'Veness',并且从'city'到'email'的所有列
    data.loc[['Andrade', 'Veness'], ['city':'email']]
    # 选择和之前相同的行,但只选择'first_name', 'address' 和 'city'这3列
    data.loc['Andrade':'Veness', ['first_name', 'address', 'city']]

    # 将下标切换为'id'
    data.set_index('id', inplace=True) # 在原有数据源上修改
    # 选择下标('id')= 487 的行
    data.loc[487]

注意:最后一行代码:data.loc[487] 不等价于 data.iloc[487], 前者是选择 'id' = 487 的行,而后者是选择第488行,DataFrame的索引可以是数字顺序的,也可以是字符串或多值的。

使用Boolean / 逻辑判断选择数据

使用 boolean 数组进行条件选择是较为常用的手段,使用boolean下标或者逻辑表达式,你可以传递给 loc 一个值为 True/False 的Series或者数组来选择那些 Series或者数组中值为 True 的行。

较多情况下,语句 data["first_name" == 'Antonio'] 会返回一个值为 True/False 的 Series 类型数据,其中 "True" 代表这一行中的 "first_name" 值为 "Antonio",这些 boolean数组可以直接如图所示传递给 loc 方法:

image

和之前一样,可以传递给 loc 第2个"参数"用来选择某些列,可以是列举的列名,也可以是用 " : " 切片的连续列,如图:

image

同样要注意:如果只选择了单独的一列,返回的是 Series 类型,同样传递一个单值list可以返回 DataFrame 类型,如图:

image

通过以下代码可以很好的理解 loc 的使用:

    # 选择 first_name 为Antonio,并且从 'city' 到 'email'的所有列
    data.loc[data['first_name'] == 'Antonio', 'city':'email']
 
    # 选择那些 email的值中是以 "hotmail.com" 结尾的行,同时选择所有列
    data.loc[data['email'].str.endswith("hotmail.com")]   
 
    # 选择那些 "last_name" 等于某些值的行
    data.loc[data['first_name'].isin(['France', 'Tyisha', 'Eric'])]   
       
    # 选择 first_name = 'Antonio' 并且 email 是以 "gmail.com"结尾的行
    data.loc[data['email'].str.endswith("gmail.com") & (data['first_name'] == 'Antonio')] 
 
    # select rows with id column between 100 and 200, and just return 'postal' and 'web' columns
    # 选择那些 id 从100到200的行,并且只返回 'postal' 和 'web' 这两列
    data.loc[(data['id'] > 100) & (data['id'] <= 200), ['postal', 'web']] 
 
    # lambda函数产生的 True/False 同样可以使用到 loc 中
    # 选择那些公司名为4个单词的行
    data.loc[data['company_name'].apply(lambda x: len(x.split(' ')) == 4)] 
 
    # 为了代码更加清晰, 选择也可以在 .loc 之外进行
    # 在 .loc 之外单独生成一个变量
    idx = data['company_name'].apply(lambda x: len(x.split(' ')) == 4)
    # 只选择 idx 值为True的那些行,并且只选择'email', 'first_name', 'company'这3列
    data.loc[idx, ['email', 'first_name', 'company']]

顺便说一下Pandas中 map(), apply()applymap()的区别

  • map() 是 Series 中的函数,DataFrame 中是没有 map() 的,map() 将函数应用于Series中的每一个元素

  • apply()applymap() 是 DataFrame 中的函数,而在Series中是没有的。他们的区别在于: apply() 将函数作用于DataFrame中的 每一个行或者列,而 applymap() 会将函数作用于DataFrame中的 每一个元素

使用 loc 修改 DataFrame 中的数据

你可以像使用 loc 查询数据那样对数据进行修改,这个操作不会返回新的数据对象而是直接在原数据上进行修改。通过这个操作,你可以根据不同的情况对数据进行修改:

    # 修改 'id' > 2000 的数据中的 'first_name' 为 "John"
    data.loc[data['id'] > 2000, "first_name"] = "John"

使用 ix 进行选择

现在pandas官方已经不推荐使用 ix 进行选择了,并且将会在 0.20.1版本从Pandas中丢弃

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容