
1.4 pandas——强大的Python数据分析工具
在数据分析领域,pandas可能是应用最为广泛的库。pandas基于强大的NumPy库构建,它提供了快速且灵活的数据结构,可以用来处理现实世界中的数据集。原始数据通常用表格形式呈现并通过.csv 格式文件进行分享。pandas为导入.csv文件提供了便捷的接口并用一种名为DataFrame的数据结构进行存储,这使得在Python中操作数据变得非常轻松。
1.4.1 pandas DataFrame
pandas DataFrame是一个二维数据结构,你可以把它看作Excel的单元格。DataFrame使你能够通过简单的指令导入.csv文件:
import pandas as pd df = pd.read_csv("raw_data.csv")
数据导入为DataFrame类型之后,我们便可以轻易地对其进行数据分析。我们将通过鸢尾属植物数据集(Iris flower Data Set)来讲解。鸢尾属植物数据集是一个很常用的数据集,它包含了几类鸢尾属植物的测量数据(萼片的长度和宽度,花瓣的长度和宽度)。首先,让我们导入加州大学欧文分校(UCI)免费提供的数据集。注意,pandas可以直接从URL导入数据集:
URL = \ '*****://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data' df = pd.read_csv(URL, names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'class'])
现在数据已经存入DataFrame,我们可以很方便地操作数据了。然后来获取数据集的汇总信息,因为了解即将要操作的数据集是很重要的。
print(df.info())
代码的执行结果如图1-9所示。

图1-9
数据集有150行,每一行有5列,其中有4列是数值形式的信息,包括sepal_ length、sepal_width、petal_length和petal_width。另外还有一列包含了非数值形式的信息,表示花的种类。
我们可以通过调用describe函数快速获取4个数值列的统计信息:
print(df.describe())
输出结果如图1-10所示。

图1-10
下一步让我们看看表中前10行的数据:
print(df.head(10))
输出结果如图1-11所示。

图1-11
很简单,对吧?pandas同样可以帮助我们轻松地进行数据清洗。例如,下面的操作可以过滤并筛选sepal_length大于5.0的行:
df2 = df.loc[df['sepal_length'] > 5.0, ]
输出结果如图1-12所示。

图1-12
通过loc命令我们可以获取一组行和列中的数据。
1.4.2 pandas中的数据可视化
探索性数据分析(EDA)也许可以称得上是机器学习工作流里最重要的一个步骤了,pandas使我们可以非常轻松地利用Python进行数据可视化。pandas提供了基于matplotlib的高级应用程序接口(API),这使得利用DataFrame数据绘制图表变得非常容易。
举个例子,可以通过对鸢尾属植物数据集进行可视化来揭示一些重要的信息。首先绘制散点图观察sepal_width 和sepal_length的关系。我们可以通过DataFrame. plot.scatter()方法轻松创建散点图,这个方法是所有DataFrame的内建方法。
# 为不同的类别定义不同的散点图图标 import matplotlib.pyplot as plt marker_shapes = ['.', '^', '*'] # 然后绘制散点图 ax = plt.axes() for i, species in enumerate(df['class'].unique()): species_data = df[df['class'] == species] species_data.plot.scatter(x='sepal_length', y='sepal_width',marker= marker_shapes[i],s=100,title="Sepal Width vs Length by Species",label=species, figsize=(10,7), ax=ax)
输出的散点图如图1-13所示。

图1-13
从散点图中我们可以洞察出一些有趣的信息。首先,sepal_width和sepal_length的关系和种类相关。Setosa(点)的sepal_width和sepal_length差不多是线性关系。相对于Setosa而言,versicolor(三角)和virginica(星号)的sepal_length要大得多。如果我们要设计一个机器学习算法来预测花的种类,那么sepal_width和sepal_length是模型需要包含的一组重要特征。
然后,画出直方图看看分布情况。和散点图一样,pandas DataFrame提供了内建的方法用于绘制直方图,使用DataFrame.plot.hist函数:
df['petal_length'].plot.hist(title='Histogram of Petal Length')
输出结果如图1-14所示。

图1-14
可以看到花瓣长度是一种双峰分布。相对于其他类型的花,某种类型的花的花瓣长度更短。同样也可以画出数据的箱线图(boxplot)。箱线图是一种重要的数据可视化工具,数据科学家使用箱线图,并基于第一四分位数、中位数、第三四分位数来理解数据的分布情况:
df.plot.box(title='Boxplot of Sepal Length & Width, and Petal Length & Width')
输出结果如图1-15所示。

图1-15
从箱线图我们可以看出sepal_width的方差远小于其他变量,而petal_length则有着最大的方差。
使用pandas直接进行数据可视化是如此得简单方便。请记住,探索性数据分析在机器学习工作流中是至关重要的一步,在本书的其他项目中,我们都会对其进行探索性数据分析。
1.4.3 使用pandas进行数据预处理
最后,让我们看看如何使用pandas进行数据预处理,尤其是如何对类别变量进行编码以及填补缺失值。
1.编码类别变量
在机器学习项目中,数据集含有类别变量是很常见的情况。以下是一些类别变量的例子。
● 性别:男性、女性。
● 日期:星期一、星期二、星期三、星期四、星期五、星期六、星期日。
● 国家:美国、英国、中国、日本。
机器学习算法(例如神经网络)是无法处理类别变量的,因为它只接收数值变量。为此我们需要在将类别变量输入机器学习算法前对其进行预处理。
将类别变量转化为数值变量的一个常用方法是独热编码(One-hot encoding),可在pandas中通过get_dummies函数实现。独热编码将n个类别变量转换为n个二元特征。案例如图1-16所示。

图1-16
从本质上看,转换后的特征是二元特征,如果表示原本的特征则置为1,否则置为0。可以想象,如果为此手动编写代码会很麻烦。幸运的是,pandas提供一个便捷的函数帮你处理这件事。首先,让我们使用图1-16中的数据在pandas中创建一个DataFrame:
df2 = pd.DataFrame({'Day': ['Monday','Tuesday','Wednesday', 'Thursday','Friday','Saturday', 'Sunday']})
输出如图1-17所示。

图1-17
在pandas中对原始数据的分类特征进行独热编码,只需要调用下面的函数:
print(pd.get_dummies(df2))
输入如图1-18所示。

图1-18
2.填充缺失数据
正如前面所探讨的,填充缺失数据是机器学习工作流中的必要步骤。真实世界的数据集非常杂乱而且通常包含缺失的数据。大多数的机器学习模型,例如神经网络遇到缺失数据是不能工作的,因此我们必须在将数据传入模型之前对其进行预处理。pandas使得处理缺失数据变得非常容易。
我们会使用前面提到的鸢尾属植物数据集来讲解如何填充缺失数据。鸢尾属植物数据集中原本并没有缺失数据,为了这个练习,我们故意删掉其中一些数据。下面的代码会在数据集中随机选择10行数据并删除其中的sepal_length值:
import numpy as np import pandas as pd # 导入iris数据集 URL = \ '*****://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data' df = pd.read_csv(URL, names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'class']) # 随机选择10行 random_index = np.random.choice(df.index, replace= False, size=10) # 将这些列中的sepal_length设置为None df.loc[random_index,'sepal_length'] = None
让我们使用修改后的数据集,看看应该如何处理缺失的数据。首先,查看有哪些缺失的数据:
print(df.isnull().any())
print函数的输出结果如图1-19所示。
果不其然,pandas告诉我们sepal_length中有缺失的数据。这个命令对找到数据集中的缺失数据很有用。
处理缺失数据的一个办法是把它们所在的行直接移除。pandas提供了一个非常方便的函数dropna来完成这个操作:
print("Number of rows before deleting: %d" % (df.shape[0])) df2 = df.dropna() print("Number of rows after deleting: %d" % (df2.shape[0]))
输出结果如图1-20所示。

图1-19

图1-20
另外一个方法是将缺失的sepal_length用其他sepal_length的均值代替:
df.sepal_length = df.sepal_length.fillna(df.sepal_length.mean())
在pandas中使用df.means()计算平均值时,pandas会自动排除缺失的值。
现在,让我们确认数据集中不再包含缺失值(如图1-21所示)。

图1-21
缺失值的问题解决后,我们可以将DataFrame传递到机器学习模型中了。
1.4.4 在神经网络项目中使用pandas
我们已经了解了如何使用pandas导入.csv格式的表格数据,并使用pandas内置函数进行预处理和数据可视化。在本书的余下内容中,如果数据是表格形式的,我们还会使用pandas。pandas在数据预处理和探索性数据分析中将起到至关重要的作用,在后续的章节我们会见证这一点。