第33单元 处理缺失数据
数据几乎从来都不是完美的。有些值是固定的(不需要担心这样的值),有些值是有问题的(你必须用加盐4的方式对待它们),而有些值是缺失的。
4“加盐”是数据加密中常用的术语,具体来说就是在原有材料(用户自定义密码)中加入其他成分(一般是用户自有且不变的因素),以此来增加系统复杂度。——译者注
pandas沿用了传统的numpy.nan(第25单元)来表示缺失数据,这样做的好处是不会将缺失数据与其他任何数字混淆,因为它的名称类似于R语言中的NA(“Not Available”,不可用)符号。pandas还提供识别和插补缺失值的函数。
造成series和frame中出现缺失值的原因有以下几个:数据可能从未被收集;数据被收集了,但由于是不恰当的值而被丢弃了;你将几个本身是完整的数据集组合起来了,但是它们的组合却不再是完整的数据集。可惜的是,在处理缺失值之前,不能进行任何严谨的数据分析。缺失值必须被删除或插补。所谓插补就是将其替换为有意义的值。下面进行详细介绍。
删除缺失数据
处理缺失数据最简单的方式是假装你从来没有得到它(“视而不见,充耳不闻”的方法)。dropna()函数可以删除部分(how="any",默认值)或者全部(how="all")无效的列(axis=0,默认值)或行(axis=1),并返回“干净的”frame对象。可以使用可选参数inplace=True直接修改原始frame,而不是创建副本。
nan_alco.dropna(how="all") ➾ Beer Wine Spirits Water ➾ State ➾ South Carolina 1.36 0.24 0.77 NaN ➾ South Dakota 1.53 0.22 0.88 NaN nan_alco.dropna(how="all", axis=1) ➾ Beer Wine Spirits ➾ State ➾ South Carolina 1.36 0.24 0.77 ➾ South Dakota 1.53 0.22 0.88 ➾ Samoa NaN NaN NaN
只删除缺失值而不破坏frame的结构是不可能的。只能对包含“脏的”单元格的整行或整列进行删除,并且完成删除操作后“干净的”frame可能是空的,这样一来什么数据都看不到了。
nan_alco.dropna() ➾ Empty DataFrame ➾ Columns: [Beer, Wine, Spirits, Water] ➾ Index: []
插补缺失数据
处理缺失值的另一种方法是插补缺失数据。插补缺失值意味着用一些有意义的、“干净的”值代替它们。当然,什么是有意义的取决于数据本身。只有数据科学家才能判断替代值是否合适。
两种最常见的插补技术是用常数(0、1等)和“干净”值的平均值替换缺失值。但首先,需要明确哪些是缺失值。
函数isnull()和notnull()是互补的。当某个值是nan时,函数isnull()返回True。当某个值不是nan时,函数notnull()返回True。请注意,根据IEEE 754的浮点数标准,表达式np.nan==np.nan为False,这使得直接比较是不可能的!
nan_alco.isnull() ➾ Beer Wine Spirits Water ➾ State ➾ South Carolina False False False True ➾ South Dakota False False False True ➾ Samoa True True True True nan_alco.notnull() ➾ Beer Wine Spirits Water ➾ State ➾ South Carolina True True True False ➾ South Dakota True True True False ➾ Samoa False False False False
下面我们通过估算平均值来修正“Spirits”列(请注意,在numpy中,连字符“-”是否定运算符):
sp = nan_alco['Spirits'] # 选中具有“脏”值的一列数据 clean = sp.notnull() # “干净”值的行编号 sp[-clean] = sp[clean].mean() # 使用平均值来修正“脏”值 nan_alco ➾ Beer Wine Spirits Water ➾ State ➾ South Carolina 1.36 0.24 0.770 NaN ➾ South Dakota 1.53 0.22 0.880 NaN ➾ Samoa NaN NaN 0.825 NaN
平均值插补的方法必须逐列(或逐行)地进行,但如果是常数插补,就可以直接应用到整个frame。函数fillna(val)是将常数val插到空缺处的最简单的方式。另外,该函数可以沿着列(axis=0,默认值)或行(axis=1),将最后一次有效观测值向前(method="ffill")或向后(method="bfill")复制。除非指定了参数inplace=True,否则该函数将返回一个新的frame或series。
nan_alco.fillna(0) ➾ Beer Wine Spirits Water ➾ State ➾ South Carolina 1.36 0.24 0.77 0 ➾ South Dakota 1.53 0.22 0.88 0 ➾ Samoa 0.00 0.00 0.00 0 nan_alco.fillna(method="ffill") ➾ Beer Wine Spirits Water ➾ State ➾ South Carolina 1.36 0.24 0.77 NaN ➾ South Dakota 1.53 0.22 0.88 NaN ➾ Samoa 1.53 0.22 0.88 NaN
替换数据
另一种处理特定的“脏”数据的方法,是根据具体情况使用“干净”值有选择地替换它们。replace(val_or_list,new_val)函数将一个值或值列表替换成一个新的值或值列表,列表的长度必须相同。除非传递inplace=True参数,否则该函数会返回一个新的frame或series。
函数combine_first(pegs)将两个frame或两个series组合在一起。它用frame/series参数中的相应值替换frame/series对象中的缺失值。从某种意义上来说,函数的参数提供了默认值。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论