[Python] 经验总结 1:数据框的切片


每个人都知道 Python 是一种高效、简洁、优雅的语言。然而 Python 也有很多坑,现在老宅开一个新系列,分享老宅在学习和实践中总结的经验和教训,不定期分享。

第一个经验就是要吐槽 总结数据框的切片。Python 有很多第三方的模块(比如 pandas 这样的数据科学神器),对提升 Python 的实用性贡献很大。然而模块多就有一个副作用:语法的不一致性。老宅在学习 pandas 的过程中就被数据框切片的复杂语法搞得挠头。

本文参考了 http://chris.friedline.net/2015-12-15-rutgers/lessons/python2/02-index-slice-subset.html,特此致谢。

数据框的切片,是在列表的切片的基础上发展起来的。不过列表是一维,数据框是二维,因此数据框切片有自己独特的方法。所以数据框的切片有两个风格:原生风格和 pandas 风格(这两个风格是老宅自己总结的…)。在总结以前,我们先构建数据集:

>>> import pandas as pd
>>> from sklearn.datasets import load_iris # 载入 iris 数据集模块
>>> iris = pd.DataFrame(load_iris()["data"]) # 载入 iris 数据集并转化为列表
>>> iris.columns = ["sepal_length", "sepal_width",
...                 "petal_length", "petal_width"] # 定义列名
>>> from string import ascii_lowercase # 载入字母表
>>> idx = []
>>> for i in ascii_lowercase:
...     for j in ascii_lowercase:
...         idx.append(i + j)
# 创建字母表排列组合
>>> iris.index = idx[:150] # 定义行名
>>> iris.head()
sepal_lengthsepal_widthpetal_lengthpetal_width
aa5.13.51.40.2
ab4.93.01.40.2
ac4.73.21.30.2
ad4.63.11.50.2
ae5.03.61.40.2

原生风格

切片单列

  • df.column 方法

直接在数据框后面使用 . 连接列名。例如:

>>> iris.sepal_length[1:5]
ab    4.9
ac    4.7
ad    4.6
ae    5.0
Name: sepal_length, dtype: float64

这个方法不需要用 "" 括上列,非常方便。不过这样有个潜在的局限:如果列名里有空格,这个方法就不好用了,就要用下面的方法。

  • df["column"] 方法

这个方法的好处是引号内可以有特殊符号,比如空格。这样切片稍微麻烦一点,但是还可以接受。

  • df[["column"]] 方法

这个方法与上面一样都用来切片单列。有什么不同呢?请看下面的例子:

>>> iris["sepal_length"][1:5]

ab    4.9
ac    4.7
ad    4.6
ae    5.0
Name: sepal_length, dtype: float64

>>> iris[["sepal_length"]][1:5]
sepal_length
ab4.9
ac4.7
ad4.6
ae5.0

单中括号和双中括号的区别在于单中括号返回的是序列,而双中括号返回的是数据框。

切片多列

  • df[["column1", "columns2"...]] 方法
    因为多个列组合在一起是一个数据框,所以必须使用双中括号来切片。列名要用引号括起来。
  • df[list] 方法
    这里就体现出不一致性了:假如我们先将想要切片的列放入一个列表,就可以使用单中括号,而且不需要使用引号。
>>> lst = ["sepal_length","petal_length"]
>>> iris[lst].head()
sepal_lengthpetal_length
aa5.11.4
ab4.91.4
ac4.71.3
ad4.61.5
ae5.01.4

切片行

  • 使用索引切片
    哪怕数据框的行已经有的自定义索引名,照样可以使用数字 0 - ~ 切片。
>>> iris[1:5]
sepal lengthsepal widthpetal lengthpetal width
ab4.93.01.40.2
ac4.73.21.30.2
ad4.63.11.50.2
ae5.03.61.40.2
  • 使用行名切片
>>> iris["ae":"ag"]
sepal_lengthsepal_widthpetal_lengthpetal_width
ae5.03.61.40.2
af5.43.91.70.4
ag4.63.41.40.3

行切片还有一个列切片不具备的功能:切片连续的行。如果数据框的行名和列名不一致,pandas 会自动判断你在切片行还是列。如果一致嘛…pandas 就不知所措了。这时候就要用到下面的 pandas 风格切片。

pandas 风格切片

df.loc[“indexes”, “columns”] 基于行、列的名称切片

注意行和列都是用的复数形式,意味着可以同时切片多行或多列。同时也可以切片范围内的行或列,使用 : 即可。

>>> iris.loc["ae":"ag", ["sepal_length","petal_length"]] 
sepal_lengthpetal_length
ae5.01.4
af5.41.7
ag4.61.4

想切片全部的行或列,只需要单独使用 : 即可。

iris.loc["ae":"ag", :] # 切片全部列
sepal_lengthsepal_widthpetal_lengthpetal_width
ae5.03.61.40.2
af5.43.91.70.4
ag4.63.41.40.3

df.iloc[“indexes”, “columns”] 基于行、列的索引切片

也可以基于行或列的数字索引切片,具备 loc 的一切结构和性质。

>>> iris.iloc[1:3, 0:2]
sepal_lengthsepal_width
ab4.93.0
ac4.73.2

好了,总结完毕,困觉觉去了~

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值