第一次作业打卡
1. 问题
【问题一】 如何删除缺失值占比超过25%的列?
//
import pandas as pd
import numpy as np
# 创建一个有不同缺失情况的dataframe对象
df_d = pd.DataFrame({'A':[np.nan,np.nan,np.nan,np.nan,np.nan,np.nan],'B':[np.nan,np.nan,np.nan,np.nan,np.nan,2],'C':[np.nan,np.nan,np.nan,np.nan,2,1],'D':[np.nan,np.nan,np.nan,3,2,1],'E':[np.nan,np.nan,4,3,2,1],'F':[np.nan,5,4,3,2,1],'G':[6,5,4,3,2,1]})
# 首先将其中所有全为缺失值的列直接删除
df_d_new_1 = df_d.dropna(axis = 1, how = 'all')
# 统计不同列缺失值数量,s是一个series对象
s = df_d_new_1.isna().sum()
# 计算整个对象的行数
row = df_d_new_1.shape[0]
# 通过索引的循环,分别计算每一列的缺失值比例,并和原dataframe行数的四分之一进行比较,大于四分之一的就会被删除
for index in s.index:
if (int(s['{}'.format(index)])) > (row/4):
df_d_new_1 = df_d_new_1.drop(columns = '{}'.format(index))
print('finished')
print(df_d_new_1)
【问题二】 什么是Nullable类型?请谈谈为什么要引入这个设计?
这是一种具有相对比较独立属性特征的缺失值类型
统一目前Pandas中比较混乱的缺失值处理符号,同时规范缺失值处理过程中对于原dataframe对象,series对象数据类型的影响
【问题三】 对于一份有缺失值的数据,可以采取哪些策略或方法深化对它的了解?
首先可以用 info() 和 isna() 方法对其中缺失值的分布情况进行了解,通过结果返回又可以通过遍历对整个dataframe对象中的所有行列缺失值分布状态进行了解
2. 练习
【练习一】现有一份虚拟数据集,列类型分别为string/浮点/整型,请解决如下问题:
(a)请以列类型读入数据,并选出C为缺失值的行。
(b)现需要将A中的部分单元转为缺失值,单元格中的最小转换概率为25%,且概率大小与所在行B列单元的值成正比。
//
pd.read_csv('data/Missing_data_one.csv').head()
A | B | C | |
---|---|---|---|
0 | not_NaN | 0.922 | 4.0 |
1 | not_NaN | 0.700 | NaN |
2 | not_NaN | 0.503 | 8.0 |
3 | not_NaN | 0.938 | 4.0 |
4 | not_NaN | 0.952 | 10.0 |
import pandas as pd
import numpy as np
import random
# 导入数据
df = pd.read_csv('data/Missing_data_one.csv').convert_dtypes()
# 筛选出C列存在缺失值的行
df_1 = df[df['C'].isna()]
print(df_1.head())
# 将前面两列的名称存入变量
column_1 = df.columns.values[0]
column_2 = df.columns.values[1]
# 确定B列的最大/最小值,方便后面概率的计算
min = int(df['{}'.format(column_2)].idxmin())
max = int(df['{}'.format(column_2)].idxmax())
# 通过循环遍历整个A列
for index in range(df.shape[0]):
# 生成一个0-1之间的随机浮点数
rand_num = random.random()
# 通过与A列该元素同行的B列数字大小确定其被填充为缺失值的概率,最小为25%,最大为100%,概率大小随着B列数字的大小变化而变化
probability = 0.25 + 0.75 * (float(df.at[index,'{}'.format(column_2)])-min)/(max-min)
# 如果随机生成的浮点数rand_num没有落在概率范围内,则表示该次命中概率,A列相应元素被填充为缺失值
if rand_num < probability:
df.loc[index,'{}'.format(column_1)] = pd.NA
print(df.head())
print('==================')
【练习二】 现有一份缺失的数据集,记录了36个人来自的地区、身高、体重、年龄和工资,请解决如下问题:
(a)统计各列缺失的比例并选出在后三列中至少有两个非缺失值的行。
(b)请结合身高列和地区列中的数据,对体重进行合理插值。
pd.read_csv('data/Missing_data_two.csv').head()
编号 | 地区 | 身高 | 体重 | 年龄 | 工资 | |
---|---|---|---|---|---|---|
0 | 1 | A | 157.50 | NaN | 47.0 | 15905.0 |
1 | 2 | B | 202.00 | 91.80 | 25.0 | NaN |
2 | 3 | C | 169.09 | 62.18 | NaN | NaN |
3 | 4 | A | 166.61 | 59.95 | 77.0 | 5434.0 |
4 | 5 | B | 185.19 | NaN | 62.0 | 4242.0 |
import pandas as pd
import numpy as np
from scipy import interpolate
# 读取数据
df = pd.read_csv('data/Missing_data_two.csv').convert_dtypes()
# 将列名称存入一个列表
columns = df.columns.values.tolist()
# 定义一个空的字典
Pom_values = {}
# 计算每列缺失值比例,并存入一个字典,与列名相对应
for column in columns:
num = int(df.shape[0])
Pom_values['{}'.format(column)] = 1 - ((int(df['{}'.format(column)].count()))/num)
# 创建一个空的列表,用于存储后三列中至少有两个非缺失值的行索引
index_list = []
# 遍历每行,分别计算其后三列的缺失值数量(因为除了后三列,其他列都没有缺失值存在,就直接遍历了整行内容,没有考虑效率)
for index in range(df.shape[0]):
num = 0
for column in columns:
if pd.isnull(df.at[index,'{}'.format(column)]) :
num += 1
if num <= 1:
index_list.append(index)
print(index_list)
print('=====')
#print(df)
df_1 = df.sort_values(by = ['地区', '身高'])
print(df_1)
print('=====')
# 首先将“地区”列中的所有不同元素存入一个列表
List_type = df['地区'].unique()
# 根据不同的地区元素将原来的大dataframe拆分成三个小的dataframe,在小的对象中,只有一个地区属性,并按身高进行排序
data0 = df[df['地区'].isin([List_type[0]])].sort_values(by = ['身高'])
data1 = df[df['地区'].isin([List_type[1]])].sort_values(by = ['身高'])
data2 = df[df['地区'].isin([List_type[2]])].sort_values(by = ['身高'])
# 在每个地区中,分别进行线性插值
#data0['体重'] = data0['体重'].fillna(method = 'pad')
data0['体重'] = data0['体重'].interpolate()
data1['体重'] = data1['体重'].interpolate()
data2['体重'] = data2['体重'].interpolate()
#print(data0)
result = data0.append([data1, data2])
print(result)