从剪贴板中创建DataFrame

假设你将一些数据储存在Excel或者Google Sheet中,你又想要尽快地将他们读取至DataFrame中。你需要选择这些数据并复制至剪贴板。然后,你可以使用​read_clipboard()函数​将他们读取至DataFrame中:

整理了几个Pandas实用技巧_python

和read_csv()类似,read_clipboard()会自动检测每一列的正确的数据类型:

整理了几个Pandas实用技巧_数据_02

让我们再复制另外一个数据至剪贴板:

整理了几个Pandas实用技巧_缺失值_03

神奇的是,pandas已经将第一列作为索引了:

整理了几个Pandas实用技巧_python_04

需要注意的是,​如果你想要你的工作在未来可复制,那么read_clipboard()并不值得推荐

将DataFrame划分为两个随机的子集

假设你想要将一个DataFrame划分为两部分,随机地将75%的行给一个DataFrame,剩下的25%的行给另一个DataFrame。

举例来说,我们的movie ratings这个DataFrame有979行:

整理了几个Pandas实用技巧_数据_05

我们可以使用​sample()函数​来随机选取75%的行,并将它们赋值给"movies_1"DataFrame:

整理了几个Pandas实用技巧_缺失值_06

接着我们使用drop()函数来舍弃“moive_1”中出现过的行,将剩下的行赋值给"movies_2"DataFrame:

整理了几个Pandas实用技巧_缺失值_07

你可以发现总的行数是正确的:

整理了几个Pandas实用技巧_缺失值_08

你还可以检查每部电影的索引,或者"moives_1":

整理了几个Pandas实用技巧_python_09

或者"moives_2":

整理了几个Pandas实用技巧_数据_10

需要注意的是,​这个方法在索引值不唯一的情况下不起作用。

**注:**该方法在机器学习或者深度学习中很有用,因为在模型训练前,我们往往需要将全部数据集按某个比例划分成训练集和测试集。该方法既简单又高效,值得学习和尝试。

多种类型过滤DataFrame

让我们先看一眼movies这个DataFrame:

In [60]:
movies.head()

Out[60]:

整理了几个Pandas实用技巧_数据_11

其中有一列是genre(类型):

整理了几个Pandas实用技巧_数据_12

比如我们想要对该DataFrame进行过滤,我们只想显示genre为Action或者Drama或者Western的电影,我们可以使用多个条件,以"or"符号分隔:

In [62]:
movies[(movies.genre == 'Action') |
(movies.genre == 'Drama') |
(movies.genre == 'Western')].head()


Out[62]:

整理了几个Pandas实用技巧_数据_13

但是,你实际上可以使用isin()函数将代码写得更加清晰,将genres列表传递给该函数:

In [63]:
movies[movies.genre.isin(['Action', 'Drama', 'Western'])].head()


Out[63]:

整理了几个Pandas实用技巧_python_14

如果你想要进行相反的过滤,也就是你将吧刚才的三种类型的电影排除掉,那么你可以在过滤条件前加上破浪号:

In [64]:
movies[~movies.genre.isin(['Action', 'Drama', 'Western'])].head()


Out[64]:

整理了几个Pandas实用技巧_数据_15

这种方法能够起作用是​因为在Python中,波浪号表示“not”操作。

DataFrame筛选数量最多类别

假设你想要对movies这个DataFrame通过genre进行过滤,但是只需要前3个数量最多的genre。

我们对genre使用​value_counts()函数​,并将它保存成counts(type为Series):

整理了几个Pandas实用技巧_缺失值_16

该Series的nlargest()函数能够轻松地计算出Series中前3个最大值:

整理了几个Pandas实用技巧_缺失值_17

事实上我们在该Series中需要的是索引:

整理了几个Pandas实用技巧_python_18

最后,我们将该索引传递给isin()函数,该函数会把它当成genre列表:

In [68]:
movies[movies.genre.isin(counts.nlargest(3).index)].head()


Out[68]:

整理了几个Pandas实用技巧_缺失值_19

这样,在DataFrame中只剩下Drame, Comdey, Action这三种类型的电影了。

处理缺失值

让我们来看一看UFO sightings这个DataFrame:

整理了几个Pandas实用技巧_数据_20

你将会注意到有些值是​缺失的​。

为了找出每一列中有多少值是缺失的,你可以使用​isna()函数​,然后再使用​sum()​:

整理了几个Pandas实用技巧_数据_21

isna()会产生一个由True和False组成的DataFrame,sum()会将所有的True值转换为1,False转换为0并把它们加起来。

类似地,你可以通过mean()和isna()函数找出每一列中缺失值的百分比。

整理了几个Pandas实用技巧_缺失值_22

如果你想要舍弃那些包含了缺失值的列,你可以使用dropna()函数:

整理了几个Pandas实用技巧_python_23

或者你想要舍弃那么缺失值占比超过10%的列,你可以给dropna()设置一个阈值:

整理了几个Pandas实用技巧_数据_24

len(ufo)返回总行数,我们将它乘以0.9,以告诉pandas保留那些至少90%的值不是缺失值的列。

一个字符串划分成多列

我们先创建另一个新的示例DataFrame:

整理了几个Pandas实用技巧_缺失值_25

如果我们需要将“name”这一列划分为三个独立的列,用来表示first, middle, last name呢?我们将会使用​str.split()函数​,告诉它​以空格进行分隔​,并将结果扩展成一个DataFrame:

整理了几个Pandas实用技巧_python_26

这三列实际上可以通过一行代码保存至原来的DataFrame:

整理了几个Pandas实用技巧_python_27

如果我们想要划分一个字符串,但是仅保留其中一个结果列呢?比如说,让我们以", "来划分location这一列:

整理了几个Pandas实用技巧_缺失值_28

如果我们只想保留第0列作为city name,我们仅需要选择那一列并保存至DataFrame:

整理了几个Pandas实用技巧_数据_29

Series扩展成DataFrame

让我们创建一个新的示例DataFrame:

整理了几个Pandas实用技巧_python_30

这里有两列,第二列包含了Python中的由整数元素组成的列表。

如果我们想要将第二列扩展成DataFrame,我们可以对那一列使用​apply()函数并传递给Series constructor​:

整理了几个Pandas实用技巧_缺失值_31

通过使用concat()函数,我们可以将原来的DataFrame和新的DataFrame组合起来:

整理了几个Pandas实用技巧_缺失值_32

对多个函数进行聚合

让我们来看一眼从Chipotle restaurant chain得到的orders这个DataFrame:

In [82]:
orders.head(10)


Out[82]:

整理了几个Pandas实用技巧_python_33

每个订单(order)都有订单号(order_id),包含一行或者多行。为了找出每个订单的总价格,你可以将那个订单号的价格(item_price)加起来。比如,这里是订单号为1的总价格:

整理了几个Pandas实用技巧_python_34

如果你想要计算每个订单的总价格,你可以对order_id使用groupby(),再对每个group的item_price进行求和。

整理了几个Pandas实用技巧_缺失值_35

但是,事实上你不可能在聚合时仅使用一个函数,比如sum()。**为了对多个函数进行聚合,你可以使用agg()函数,**传给它一个函数列表,比如sum()和count():

整理了几个Pandas实用技巧_python_36

这将告诉我们没定订单的总价格和数量。

聚合结果与DataFrame组合

让我们再看一眼orders这个DataFrame:

In [86]:
orders.head(10)

Out[86]:

整理了几个Pandas实用技巧_缺失值_37

如果我们想要增加新的一列,用于展示每个订单的总价格呢?回忆一下,我们通过使用sum()函数得到了总价格:

整理了几个Pandas实用技巧_数据_38

sum()是一个聚合函数,这表明它返回输入数据的精简版本(reduced version )。

换句话说,sum()函数的输出:

整理了几个Pandas实用技巧_数据_39

比这个函数的输入要小:

整理了几个Pandas实用技巧_python_40

解决的办法是​使用transform()函数****,它会执行相同的操作但是返回与输入数据相同的形状​:

整理了几个Pandas实用技巧_python_41

我们将这个结果存储至DataFrame中新的一列:

In [91]:
orders['total_price'] = total_price
orders.head(10)


Out[91]:

整理了几个Pandas实用技巧_python_42

你可以看到,每个订单的总价格在每一行中显示出来了。

这样我们就能方便地甲酸每个订单的价格占该订单的总价格的百分比:

In [92]:
orders['percent_of_total'] = orders.item_price / orders.total_price
orders.head(10)


In [92]:

整理了几个Pandas实用技巧_数据_43

选取行和列的切片

让我们看一眼另一个数据集:

In [93]:
titanic.head()


Out[93]:

整理了几个Pandas实用技巧_缺失值_44

这就是著名的Titanic数据集,它保存了Titanic上乘客的信息以及他们是否存活。

如果你想要对这个数据集做一个数值方面的总结,你可以使用describe()函数:

整理了几个Pandas实用技巧_缺失值_45

但是,这个DataFrame结果可能比你想要的信息显示得更多。

如果你想对这个结果进行过滤,只想显示“五数概括法”(five-number summary)的信息,你可以使用​loc函数并传递"min"到"max"的切片​:

整理了几个Pandas实用技巧_缺失值_46

如果你不是对所有列都感兴趣,你也可以传递列名的切片:

整理了几个Pandas实用技巧_python_47

整理了几个Pandas实用技巧_数据_48

觉得文章不错,请分享给更多人