根据所获得的数据,处理不符合实际情况的数据
常用处理方法:
- 直接丢弃异常值(包括重复数据
- Pandas:drop()/dropna()/drop_duplicated()
- 用一个新的属性、值替代原值(中位数、众数等)
- Pandas:fillna()
- 针对连续型的数值,可以用插值
- Pandas:interpolate()
小数据练习:
去除空值、标注异常值、去除重复值等
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3, 3, 5, 6], 'B': ['B1', 'B2', 'B3', 'B2', 'B5', 'B6'],
'C': [1.0, 2.5, None, 4.0, 5.0, 6.0], 'D': ['D1', 'D2', 'E3', 'D4', None, 'D5'],
'E': [0.1, 8.0, 10.0, 12.0, 9.0, 12.0]})
print(df)
# 数值的空值表示为NaN,而字符串的空值则表示为None
print(df.isnull())
# 去除所有空值
print(df.dropna())
# 去除部分空值(删除C列的空值)
print(df.dropna(subset=['C']))
# 查看重复值
print(df.duplicated(['A']))
# A为重复的且B也是重复的才能算是重复
print(df.duplicated(['A','B']))
# keep 的值有: first/last/false false表示都不要
print(df.drop_duplicates(['A'], keep='first'))
# 标注异常值
print(df.fillna('b*'))
# 异常值填入均值
print(df.fillna(df['C'].mean()))
# 填入插值
# 相邻两值的均值
print(df['C'].interpolate())
# 样条插值,其他方法名称自行百度
print(df['C'].interpolate(method="spline", order=3))
# 四分位数
up_q = df['E'].quantile(0.75)
low_q = df['E'].quantile(0.25)
# 查看间距
q_int = up_q - low_q
k = 1.5
# 去除D列异常值(数值大于low_q - k*q_int,并且数值小于up_q + k*q_int)
print([df[df['E'] > low_q - k*q_int][df['E'] < up_q + k*q_int]])
# 删除指定行
print(df.drop(1))
# 删除D列中不是以D开头的值
print(df[[True if item.startswith('E') else False for item in list(df['D'].values)]])
实战数据清洗过程
根据实际情况,排除不可能存在的数据。每个项目中去除数据都需要根据使用场景而言。
例如某人的购物记录:不存在消费次数大于0而消费金额小于0的情况存在等
import pandas as pd
data_file = '..\\project_07\\version2_chapter7\\demo\\data\\air_data.csv'
cleaned_file = '..\\project_07\\version2_chapter7\\demo\\tmp\\data_cleaned.csv'
# 读取数据
airline_data = pd.read_csv(data_file, encoding='utf-8')
print('原始数据的形状为:', airline_data.shape)
# 去除票价记录为空的记录
airline_not_null = airline_data.loc[airline_data['SUM_YR_1'].notnull() & airline_data['SUM_YR_2'].notnull(), :]
print('删除缺失记录后数据的形状为:', airline_not_null.shape)
# 只保留票价非零的,或者平均折扣率不为0且总飞行公里数大于0的记录
index1 = airline_not_null['SUM_YR_1'] !=0
index2 = airline_not_null['SUM_YR_2'] !=0
index3 = (airline_not_null['SEG_KM_SUM'] > 0) & (airline_data['avg_discount'] != 0)
# 去除年龄大于100的记录
index4 = airline_not_null['AGE'] > 100
airline = airline_data[(index1|index2) & index3 & ~index4]
print('数据清洗后数据的形状为:', airline.shape)
# 保存结果
airline.to_csv(cleaned_file)
注:项目来源于书《Python数据分析与挖掘实战(第二版)》