在数据分析和建模的过程中,相当多的时间要用在数据准备上:加载、清理、转换以及重塑。
一、处理缺失数据
在pandas中,我们采用了R语言中的惯用法,即将缺失值表示为NA,它表示不可用not available。在统计应用中,NA数据可能是不存在的数据或者虽然存在,但是没有观察到(例如,数据采集中发生了问题)。当进行数据清洗以进行分析时,最好直接对缺失数据进行分析,以判断数据采集的问题或缺失数据可能导致的偏差。
Python内置的None值在对象数组中也可以作为NA。
处理缺失数据的方法有:
1、滤除缺失数据
2、填充缺失数据
填充用fillna函数,它的参数有:
其中method的插值方法可以用前面介绍过的reindex方法
二、数据转换
1、移除重复数据
DataFrame的duplicated方法返回一个布尔型Series,表示各行是否是重复行(前面出现过的行):
还有一个与此相关的drop_duplicates方法,它会返回一个DataFrame,重复的数组会标为False:
这两个方法默认会判断全部列,你也可以指定部分列进行重复项判断。假设我们还有一列值,且只希望根据k1列过滤重复项:
duplicated和drop_duplicates默认保留的是第一个出现的值组合。传入keep='last'则保留最后一个:
2、利用函数或映射进行数据转换
添加一列表示该肉类食物来源的动物类型:
Series的map方法可以接受一个函数或含有映射关系的字典型对象:
传入一个能够完成全部这些工作的函数:
3、替换值
利用fillna方法填充缺失数据可以看做值替换的一种特殊情况。另一种方法replace
4、重命名轴索引
跟Series中的值一样,轴标签也可以通过函数或映射进行转换,从而得到一个新的不同标签的对象。轴还可以被就地修改,而无需新建一个数据结构。
如果想要创建数据集的转换版(而不是修改原始数据),比较实用的方法是rename:
5、离散化和面元划分
为了便于分析,连续数据常常被离散化或拆分为“面元”(bin)。假设有一组人员数据,而你希望将它们划分为不同的年龄组:
将这些数据划分为“18到25”、“26到35”、“35到60”以及“60以上”几个面元。要实现该功能,你需要使用pandas的cut函数:
pandas返回的是一个特殊的Categorical对象。结果展示了pandas.cut划分的面元。你可以将其看做一组表示面元名称的字符串。它的底层含有一个表示不同分类名称的类型数组,以及一个codes属性中的年龄数据的标签:
向cut传入的是面元的数量而不是确切的面元边界,则它会根据数据的最小值和最大值计算等长面元:
qcut是一个非常类似于cut的函数,它可以根据样本分位数对数据进行面元划分。根据数据的分布情况,cut可能无法使各个面元中含有相同数量的数据点。而qcut由于使用的是样本分位数,因此可以得到大小基本相等的面元:
与cut类似,你也可以传递自定义的分位数(0到1之间的数值,包含端点):
6、检测和过滤异常值
函数sign(x),这是一个符号函数,用于把函数的符号析离出来,在数学和计算机运算中,其功能是取某个数的符号(正或负):
当x>0,sign(x)=1;
当x=0,sign(x)=0;
当x<0, sign(x)=-1;
根据这些条件,就可以对值进行设置。下面的代码可以将值限制在区间-3到3以内:
根据数据的值是正还是负,np.sign(data)可以生成1和-1:
7、排列和随机采样
利用numpy.random.permutation函数可以轻松实现对Series或DataFrame的列的排列工作(permuting,随机重排序)。传入的值要小于等于轴的长度,会返回一个新顺序的整数数组。
如果不想用替换的方式选取随机子集,可以在Series和DataFrame上使用sample方法:
8、计算指标/哑变量
另一种常用于统计建模或机器学习的转换方式是:将分类变量(categorical variable)转换为“哑变量”或“指标矩阵”。
如果DataFrame的某一列中含有k个不同的值,则可以派生出一个k列矩阵或DataFrame(其值全为1和0)。pandas有一个get_dummies函数可以实现该功能
DataFrame中的某行同属于多个分类:
一个对统计应用有用的秘诀是:结合get_dummies和诸如cut之类的离散化函数:
三、字符串操作
1、字符串对象方法
Python内置的字符串方法:
2、正则表达式
正则表达式提供了一种灵活的在文本中搜索或匹配(通常比前者复杂)字符串模式的方式。正则表达式,常称作regex,re模块的函数可以分为三个大类:模式匹配、替换以及拆分。当然,它们之间是相辅相成的。一个regex描述了需要在文本中定位的一个模式,它可以用于许多目的。
假设我想要拆分一个字符串,分隔符为数量不定的一组空白符(制表符、空格、换行符等)。描述一个或多个空白符的regex是\s+:
调用re.split('\s+',text)时,正则表达式会先被编译,然后再在text上调用其split方法。你可以用re.compile自己编译regex以得到一个可重用的regex对象:
匹配regex的所有模式,则可以使用findall方法:
match和search跟findall功能类似。findall返回的是字符串中所有的匹配项,而search则只返回第一个匹配项。match更加严格,它只匹配字符串的首部:
不仅想要找出电子邮件地址,还想将各个地址分成3个部分:用户名、域名以及域后缀。要实现此功能,只需将待分段的模式的各部分用圆括号包起来即可:
3、pandas的矢量化字符串函数
部分矢量化字符串方法通过data.map,所有字符串和正则表达式方法都能被应用于(传入lambda表达式或其他函数)各个值,但是如果存在NA(null)就会报错。为了解决这个问题,Series有一些能够跳过NA值的面向数组方法,进行字符串操作。通过Series的str属性即可访问这些方法。
有两个办法可以实现矢量化的元素获取操作:要么使用str.get,要么在str属性上使用索引:
网友评论