任务
最近在研究UCI machine learning的Diabetes 130 US hospitals for years 1999-2008 数据集。
数据集中存在缺失值,用‘?’表示。
现在需要回答以下问题:
1.每列中是否存在缺失值?
2.若存在缺失值,缺失值的数目是多少,占比多少?
解决方案
- 方案
先是针对这种情景下了一段代码:
raw_data是导入为DataFrame的数据集。只要object列才会有字符型的缺失值。浮点列或整数列不可能存在字符串型的缺失值。
for i in raw_data.columns:
if raw_data[i].dtype == 'object': #只有object的列才会出现缺失值
num = 0 # 缺失值个数,初始化为0
for j in raw_data[i]: # 遍历该列所有值
if j == '?': # 如果是缺失值
num = num + 1 # 则计数
print("{} {} {:.2%}".format(i,num,num / len(raw_data[i]))) #展示缺失值
- 优化方案
在这个基础上,想扩展到更普遍的缺失值分析,要增加以下三个功能:
1.如果缺失值是非’?'的字符串,也能运行
2.如果缺失值是整型,如0,也能运行
3.如果想查看所有列的缺失值分析,也可以;如果只想查看存在缺失的列的情况,也可以
为了实现以上的需求,将代码封装为以下函数:
def check_nan(nan, raw_data,all):
'''
参数:nan = 缺失值,可以是字符串,也可以是整型
raw_data = 要处理的数据表,类型是DataFrame
all = 1表示查看全部列的缺失值情况;0表示只看存在缺失值的列的情况
返回值:无
功能:打印出数据表中,每个特征的缺失值数量,百分比
原理:缺失值为字符串,则必只存在object类的列中;缺失值为整型,则必只存在非object的列中。
'''
for i in raw_data.columns: # 取出所有列名
num = 0 # 缺失值个数,初始化为0
nan_str = isinstance(nan,str) # 判断nan是否为字符串
i_object = raw_data[i].dtype == 'object' # 判断第i列是否为object类
if ((nan_str == True and i_object == True) or ( nan_str == False and i_object == False)):
for j in raw_data[i]: # 遍历该列所有值
if j == nan: # 如果是缺失值
num = num + 1 # 则计数
if(all == 1): # 展示全部列的缺失值情况
print("{:<30} {:<30} {:.2%}".format(i,num,num / len(raw_data[i])))
else:
if(num != 0): # 展示存在缺失值的列的情况
print("{:<30} {:<30} {:.2%}".format(i,num,num / len(raw_data[i])))
用以下代码运行即可。
import pandas as pd
check_nan('?',raw_data,0)
结果如下:
race 2273 2.23%
weight 98569 96.86%
payer_code 40256 39.56%
medical_specialty 49949 49.08%
diag_1 21 0.02%
diag_2 358 0.35%
diag_3 1423 1.40%