13.1 pandas与模型代码的接口
模型开发的通常工作流是使用pandas进行数据加载和清洗,然后切换到建模库进行建模。开发模型的重要一环是机器学习中的“特征工程”。它可以描述从原始数据集中提取信息的任何数据转换或分析,这些数据集可能在建模中有用。本书中学习的数据聚合和GroupBy工具常用于特征工程中。
优秀的特征工程超出了本书的范围,我会尽量直白地介绍一些用于数据操作和建模切换的方法。
pandas与其它分析库通常是靠NumPy的数组联系起来的。将DataFrame转换为NumPy数组,可以使用.values属性:
In [10]: import pandas as pdIn [11]: import numpy as npIn [12]: data = pd.DataFrame({....: 'x0': [1, 2, 3, 4, 5],....: 'x1': [0.01, -0.01, 0.25, -4.1, 0.],....: 'y': [-1.5, 0., 3.6, 1.3, -2.]})In [13]: dataOut[13]:x0 x1 y0 1 0.01 -1.51 2 -0.01 0.02 3 0.25 3.63 4 -4.10 1.34 5 0.00 -2.0In [14]: data.columnsOut[14]: Index(['x0', 'x1', 'y'], dtype='object')In [15]: data.valuesOut[15]:array([[ 1. , 0.01, -1.5 ],[ 2. , -0.01, 0. ],[ 3. , 0.25, 3.6 ],[ 4. , -4.1 , 1.3 ],[ 5. , 0. , -2. ]])
要转换回DataFrame,可以传递一个二维ndarray,可带有列名:
In [16]: df2 = pd.DataFrame(data.values, columns=['one', 'two', 'three'])In [17]: df2Out[17]:one two three0 1.0 0.01 -1.51 2.0 -0.01 0.02 3.0 0.25 3.63 4.0 -4.10 1.34 5.0 0.00 -2.0
笔记:最好当数据是均匀的时候使用.values属性。例如,全是数值类型。如果数据是不均匀的,结果会是Python对象的ndarray:
In [18]: df3 = data.copy()In [19]: df3['strings'] = ['a', 'b', 'c', 'd', 'e']In [20]: df3Out[20]:x0 x1 y strings0 1 0.01 -1.5 a1 2 -0.01 0.0 b2 3 0.25 3.6 c3 4 -4.10 1.3 d4 5 0.00 -2.0 eIn [21]: df3.valuesOut[21]:array([[1, 0.01, -1.5, 'a'],[2, -0.01, 0.0, 'b'],[3, 0.25, 3.6, 'c'],[4, -4.1, 1.3, 'd'],[5, 0.0, -2.0, 'e']], dtype=object)
对于一些模型,你可能只想使用列的子集。我建议你使用loc,用values作索引:
In [22]: model_cols = ['x0', 'x1']In [23]: data.loc[:, model_cols].valuesOut[23]:array([[ 1. , 0.01],[ 2. , -0.01],[ 3. , 0.25],[ 4. , -4.1 ],[ 5. , 0. ]])
一些库原生支持pandas,会自动完成工作:从DataFrame转换到NumPy,将模型的参数名添加到输出表的列或Series。其它情况,你可以手工进行“元数据管理”。
在第12章,我们学习了pandas的Categorical类型和pandas.get_dummies函数。假设数据集中有一个非数值列:
In [24]: data['category'] = pd.Categorical(['a', 'b', 'a', 'a', 'b'],....: categories=['a', 'b'])In [25]: dataOut[25]:x0 x1 y category0 1 0.01 -1.5 a1 2 -0.01 0.0 b2 3 0.25 3.6 a3 4 -4.10 1.3 a4 5 0.00 -2.0 b
如果我们想替换category列为虚变量,我们可以创建虚变量,删除category列,然后添加到结果:
In [26]: dummies = pd.get_dummies(data.category, prefix='category')In [27]: data_with_dummies = data.drop('category', axis=1).join(dummies)In [28]: data_with_dummiesOut[28]:x0 x1 y category_a category_b0 1 0.01 -1.5 1 01 2 -0.01 0.0 0 12 3 0.25 3.6 1 03 4 -4.10 1.3 1 04 5 0.00 -2.0 0 1
用虚变量拟合某些统计模型会有一些细微差别。当你不只有数字列时,使用Patsy(下一节的主题)可能更简单,更不容易出错。
