(二)Pandas切片

切片应该算是pandas的基础了,我们要增删改查数据,首先要定位到数据,切片是定位到数据的一种直观而又简单的方式。

pandas切片方式:

iloc(integer-location):通过下标或boolean数组切片数据

loc(location):通过标签或boolean数组切片数据

[ ]:方括号运算符,可以通过下标、标签或boolean数组切片数据

ix:相当于loc和iloc的综合版本,既可以按标签切片,又可以按下标切片。也就是说,ix可以识别你是想按照标签切片,还是按照下标切片,功能和iloc、loc完全重复,现在已经被弃用了,2.0已经没有这个api了。

还以下图的df为例:

1、iloc

下标是客观存在的,不光是python,对于很多其他语言一样,序列数据类型,可以通过从0开始的整数作为下标来获取序列中的值。在python中,二维切片以逗号(,)分隔,逗号左边是行,右边是列,如果没有逗号,那就是切行

iloc切片左闭右开,和python的切片规则是一样的

import pandas as pd

scores = [23, 88, 12], [99, 88, 100], [44, 77, 68]
df = pd.DataFrame(scores, index=['张三', '李四', '王二麻子'], columns=['语文', '数学', '英语'])

print(df.iloc[0, 0]) # 获取df的第一个数据
"""
23
"""

print(df.iloc[:, :]) # 获取一个和df完全一样的dataframe
"""
      语文  数学   英语
张三    23  88   12
李四    99  88  100
王二麻子  44  77   68
"""

print(df.iloc[0, :]) # 获取第一行,返回一个Series,名字是第一行的标签名
"""
语文    23
数学    88
英语    12
Name: 张三, dtype: int64
"""

print(df.iloc[:, 0::2]) # 获取从第一列开始,下标间隔为2的列,返回一个新的dataframe
"""
      语文   英语
张三    23   12
李四    99  100
王二麻子  44   68
"""

print(df.iloc[:, 0]) # 获取第一列,返回一个Series,名字是第一列的列名
"""
张三      23
李四      99
王二麻子    44
Name: 语文, dtype: int64
"""

print(df.iloc[:, [0, 2]]) # 获取第一列和第3列,返回一个新的dataframe
"""
      语文   英语
张三    23   12
李四    99  100
王二麻子  44   68
"""

2、loc

标签是pandas特有的,pandas给每一行每一列都命名一个名字来作为标签,如果代码中没有指定标签名,则pandas会使用下标来作为标签。

loc切片左闭右闭

import pandas as pd

scores = [23, 88, 12], [99, 88, 100], [44, 77, 68]
df = pd.DataFrame(scores, index=['张三', '李四', '王二麻子'], columns=['语文', '数学', '英语'])

print(df.loc['张三', "语文"]) # 获取"张三"的"语文"分数
"""
23
"""

print(df.loc[:, :]) # 获取一个和df一样的dataframe
"""
      语文  数学   英语
张三    23  88   12
李四    99  88  100
王二麻子  44  77   68
"""

print(df.loc["张三", :]) # 获取"张三"的所有成绩
"""
语文    23
数学    88
英语    12
Name: 张三, dtype: int64
"""

print(df.loc[:, "语文"]) # 获取所有人的"语文"成绩
"""
张三      23
李四      99
王二麻子    44
Name: 语文, dtype: int64
"""

print(df.loc[:, ["语文", "英语"]]) # 获取所有人的"语文"和"英语"成绩
"""
      语文   英语
张三    23   12
李四    99  100
王二麻子  44   68
"""

print(df.loc[:, "语文":"英语"]) # 获取df中所有人的"语文"到"英语"的所有科目的成绩
"""
      语文  数学   英语
张三    23  88   12
李四    99  88  100
王二麻子  44  77   68
"""

3、[]运算符

① pandas [ ]运算符 不支持二维切片,即不能[i, j]

df = pd.DataFrame({"语文": [23, 99, 44], "数学": [88, 88, 77], "英语": [12, 100, 68]}, index=["张三", "李四", "王二麻子"])
print(df["张三", "英语"])
"""
KeyError: ('张三', '英语')
"""


② 切列只能使用标签来切,不能通过下标;切多列必须传递列表,不能用冒号(:)

df = pd.DataFrame({"语文": [23, 99, 44], "数学": [88, 88, 77], "英语": [12, 100, 68]}, index=["张三", "李四", "王二麻子"])

print(df)
"""
      语文  数学   英语
张三    23  88   12
李四    99  88  100
王二麻子  44  77   68
"""

print(df[0])  # KeyError: 0 , 因为没有列名是0

print(df["语文"])
"""
张三      23
李四      99
王二麻子    44
Name: 语文, dtype: int64
"""

print(df["语文":"数学"])  # Empty DataFrame

print(df[["语文", "数学"]])
"""
      语文  数学
张三    23  88
李四    99  88
王二麻子  44  77
"""

③ 切行必须且只能使用冒号(:)。确实如此,因为[ ]不支持二维切片,所以切行和切列用法不能有任何重合,不然就有歧义,无法区分是切行还是切列

df = pd.DataFrame({"语文": [23, 99, 44], "数学": [88, 88, 77], "英语": [12, 100, 68]}, index=["张三", "李四", "王二麻子"])

print(df)
"""
      语文  数学   英语
张三    23  88   12
李四    99  88  100
王二麻子  44  77   68
"""

print(df["张三"])  # KeyError: '张三', 没用 : 就认为是切列,又没列名叫张三,所以报错


print(df["张三":"张三"])  # 可以用标签切行,标签切则左闭右闭
"""
    语文  数学  英语
张三  23  88  12
"""

print(df[0:1])  # 也可以用下标来切行,下标切则左闭右开
"""
    语文  数学  英语
张三  23  88  12
"""

print(df[:])
"""
      语文  数学   英语
张三    23  88   12
李四    99  88  100
王二麻子  44  77   68
"""

其实 [ ] 运算符更像是对iloc和loc的一个补充,比如我们要取所有人的语文成绩,如果是用loc要这么做:

df.loc[:, "语文"]

这是没办法的,因为loc的规则就是优先切行,切列部分只能在逗号(,)后面,但是如果用[]就很简单了:

df["语文"]

所以说iloc、loc、[] 三种切片方式是属于侧重点各不相同,只是为了应对不同的切片条件和要求,虽然可能一个切片要求用三种方式都能实现,但是我们不应该关注他们的替代性,而是关注各自的侧重性,选出当前条件下最简便的切片方式。

Boolean数组切片

前面我们说了,不论哪种方式都可以传递一个Boolean数组来进行切片,数组的长度必须和当前所切的维度的长度一致,即切行就必须等于行数,切列就必须等于列数。True代表选中数据,False代表不选中数据。

这里要说明一下,[ ] 运算符使用Boolean数组切片只能切行,切不了列

还是以上面的数据为例,我们现在要选出语文成绩及格的人:

print(df[[False, True, False]])
"""
    语文  数学   英语
李四  99  88  100
"""

逻辑运算

在pandas中,将Series与一个数值比较,会得到一个与自身形状完全相同且全是布尔值的Series,

前面说过,切片时可以传递Boolean数组,这就是pandas切片可以使用逻辑运算的理论基础

还是以上面例子来说,我们要筛选出语文成绩及格的人,首先我们要切出所有人的语文成绩:

df["语文"]

和数值60做判断:

df["语文"]>=60

用得到的Boolean数组来筛选数据:

df[df["语文"] >= 60]

无论多么复杂的逻辑表达式,核心原理就是这样。

1、逻辑与

pandas使用 & 来表示逻辑与。

筛选语文和数学都及格的同学:

df[(df["语文"] >= 60) & (df["数学"] >= 60)]
"""
    语文  数学  英语
李四  89  80  90
王五  76  60  44
"""

2、逻辑或

pandas使用 | 来表示逻辑或。

筛选语文或者数学及格的同学:

df[(df["语文"] >= 60) | (df["数学"] >= 60)]
"""
    语文  数学  英语
张三  11  99  66
李四  89  80  90
王五  76  60  44
"""

3、逻辑非

pandas使用 ~ 来表示逻辑非

筛选语文成绩不及格的同学:

df[~(df["语文"] >= 60)]
"""
    语文  数学  英语
张三  11  99  66
"""

4、all() 与 any() 方法

筛选没有挂科的同学:

df[(df >= 60).all(axis=1)]
"""
    语文  数学  英语
李四  89  80  90
"""

筛选至少有一科没挂科的同学:

df[(df >= 60).any(axis=1)]
"""
    语文  数学  英语
张三  12  99  66
李四  89  80  90
王五  76  60  44
"""

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值