第一个经验就是要吐槽 总结数据框的切片。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_length | sepal_width | petal_length | petal_width | |
---|---|---|---|---|
aa | 5.1 | 3.5 | 1.4 | 0.2 |
ab | 4.9 | 3.0 | 1.4 | 0.2 |
ac | 4.7 | 3.2 | 1.3 | 0.2 |
ad | 4.6 | 3.1 | 1.5 | 0.2 |
ae | 5.0 | 3.6 | 1.4 | 0.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 | |
---|---|
ab | 4.9 |
ac | 4.7 |
ad | 4.6 |
ae | 5.0 |
单中括号和双中括号的区别在于单中括号返回的是序列,而双中括号返回的是数据框。
df[["column1", "columns2"...]]
方法df[list]
方法>>> lst = ["sepal_length","petal_length"]
>>> iris[lst].head()
sepal_length | petal_length | |
---|---|---|
aa | 5.1 | 1.4 |
ab | 4.9 | 1.4 |
ac | 4.7 | 1.3 |
ad | 4.6 | 1.5 |
ae | 5.0 | 1.4 |
>>> iris[1:5]
sepal length | sepal width | petal length | petal width | |
---|---|---|---|---|
ab | 4.9 | 3.0 | 1.4 | 0.2 |
ac | 4.7 | 3.2 | 1.3 | 0.2 |
ad | 4.6 | 3.1 | 1.5 | 0.2 |
ae | 5.0 | 3.6 | 1.4 | 0.2 |
>>> iris["ae":"ag"]
sepal_length | sepal_width | petal_length | petal_width | |
---|---|---|---|---|
ae | 5.0 | 3.6 | 1.4 | 0.2 |
af | 5.4 | 3.9 | 1.7 | 0.4 |
ag | 4.6 | 3.4 | 1.4 | 0.3 |
行切片还有一个列切片不具备的功能:切片连续的行。如果数据框的行名和列名不一致,pandas 会自动判断你在切片行还是列。如果一致嘛…pandas 就不知所措了。这时候就要用到下面的 pandas 风格切片。
注意行和列都是用的复数形式,意味着可以同时切片多行或多列。同时也可以切片范围内的行或列,使用 :
即可。
>>> iris.loc["ae":"ag", ["sepal_length","petal_length"]]
sepal_length | petal_length | |
---|---|---|
ae | 5.0 | 1.4 |
af | 5.4 | 1.7 |
ag | 4.6 | 1.4 |
想切片全部的行或列,只需要单独使用 :
即可。
iris.loc["ae":"ag", :] # 切片全部列
sepal_length | sepal_width | petal_length | petal_width | |
---|---|---|---|---|
ae | 5.0 | 3.6 | 1.4 | 0.2 |
af | 5.4 | 3.9 | 1.7 | 0.4 |
ag | 4.6 | 3.4 | 1.4 | 0.3 |
也可以基于行或列的数字索引切片,具备 loc
的一切结构和性质。
>>> iris.iloc[1:3, 0:2]
sepal_length | sepal_width | |
---|---|---|
ab | 4.9 | 3.0 |
ac | 4.7 | 3.2 |
好了,总结完毕,困觉觉去了~