数据规整(数据预处理,数据清洗)
数据规整的一般分类:
- 清理
- 转换
- 合并
- 重塑
Pandas数据规整-清理:
对指定数据(如缺失数据、重复数据)进行处理(检查、替换、删除)
- 缺失值的表示:np.nan
- 检查缺失值:isnull(),notnull(),info()
- 删除缺失值:dropna()
- 填充缺失值:fillna()
- 替换值(填充缺失值是替换值的一种情况):replace()
- 移除重复数据
- 检测和过滤异常值
a = np.array([2,4,5,7,8,9]) a + 10 # result array([12, 14, 15, 17, 18, 19]) b = np.array([None,1,4,6,8,4,23,67]) b + 10 # result TypeError: unsupported operand type(s) for +: 'NoneType' and 'int' 结论:缺失值导致报错
使用Numpy的缺失值数据类型:np.nan
缺失值运算不会报错,和缺失值进行运算,结果还是缺失值
a = np.array([np.nan,1,4,5]) a + 10 a.sum() # 任何数组和缺失值计算,结果还是缺失值 np.nansum(a) np.nanmean(a) # result 3.3333333333333335 ,缺失值不参与运算 nan专有运算方法,会跳过缺失值,直接计算正常值,缺失值不参与运算 np.nansum(c) np.nanmean(c)
使用Pandas缺失值计算¶
Pandas中,不论缺失值是 None 还是 np.nan ,都会转化为 NaN 的形式
NaN:非数字,not a number,Pandas中它表示缺失或NA值,便于被检测出来
本质上就是np.nan
Pandas的对象可以跳过缺失值直接进行运算
b = pd.Series([1,2,np.nan,4,None,6]) b+10 #reslut #0 11.0 #1 12.0 #2 NaN #3 14.0 #4 NaN #5 16.0 b.mean() # 4.0 # 缺失值赋值 b[0] = np.nan b c = pd.DataFrame([[1,np.nan,3], [4,5,6], [np.nan,8,9]]) c.sum(axis=1)
通过函数检查数据中是否含有缺失值
检查单个空值
单个空值,底层类型为 np.nan,不能直接比较是否相同
# 单个空值,底层类型为 np.nan,不能直接比较是否相同 np.nan == np.nan # 单个np.nan空值,可以用 np.isnan() 方法判断是否是空值 np.isnan(np.nan) # 整体判断,表格中各列缺失值情况 c.info() # dataframe np.isnan(c) np.isnan(b) # series
isnull()和notnull()
- isnull():缺失值返回True,正常值返回False
- notnull():正常值返回True,缺失值返回False
b.isnull() # 过滤非空 b[-b.isnull()] b.notnull() # 同上, 选中所有非缺失值 b[b.notnull()] # dataframe 使用isnull notnull的时候无法具体分清 c.isnull() c[c.isnull()] c.notnull() c[c.notnull()] 结论:DataFrame不能通过布尔查询方式过滤缺失值,必须使用Pandas的特定方法过滤 查到缺失值后,Series可以直接过滤,DataFrame需要进一步处理(填充或删除)
去除缺失值,只保留有效值
# series b.dropna() # 等同于上:查询所有非缺失值 b[b.notnull()] # dataframe c.dropna() # 默认按行 c.dropna(axis=1) # 按列删除 # 增加一列全部为缺失值的数据 c[3] = np.nan # 行或列,有1个缺失值即删除 c.dropna(axis=1) # 简写,默认 c.dropna(axis=1, how='any') # 行或列必须全部都是缺失值才删 c.dropna(axis=1, how='all') c.dropna(thresh=3) # 行非缺失值数量大于等于3个,保留
填充缺失值
缺失值问题除了删除所在行列以外,还可以通过填充值解决
fillna()函数参数
c.loc[0, 1] = np.nan c.loc[1:3,0] = np.nan c.at[3,3] =100 #导致出现了第四行数据 c[3] = np.nan c.fillna(method='ffill') c.fillna(method='ffill',limit=3) # 设置填充改变的数量,limit=3每一列可以有三行数据改变
替换值
利用fillna方法填充缺失数据是值替换的一种特殊情况, replace方法用作替换值更简单、更灵活
data = pd.Series([1,-999,2,-999,-1000,3]) # 替换单值 data.replace(-999, np.nan) # 替换多值, 多个值替换为1个 data.replace([-999, -1000], np.nan) # 多个值替换为不同数值 data.replace([-999, -1000], [0, 1]) data.replace({-999: 0, -1000: 1}) #dataframe也是如此,直接替换值 c.replace(1,-1)
映射数据替换
map除了自定义函数运算,还是一种映射转换元素以及其他数据清理工作的便捷方式
a = pd.DataFrame([['鬃刷','皮带','煎蛋','观赏'],[10,20,30,40]]).T # 转置 y = {'鬃刷': '猪', '皮带': '牛', '观赏': '鱼', '衣服': '棉花'} a[0].map(y)
移除重复数据
移除DataFrame的重复行
data = pd.DataFrame({'k1':['one'] * 3 + ['two'] * 4,'k2':[1,1,2,3,3,4,4]}) # 布尔型Series,各列重复值交集 data.duplicated() # 重复行的移除 data.drop_duplicates() data[-data.duplicated()] # 移除自定义列重复行 data.drop_duplicates('k1') #keep : {‘first’, ‘last’, False}, # first默认留下第一次出现的值 data.drop_duplicates(['k1', 'k2']) data.drop_duplicates(['k1', 'k2'], keep='first') # last,留下最后一次出现的值 data.drop_duplicates(['k1', 'k2'], keep='last') # 保留非全列的行数据时,结果行会不同 data.drop_duplicates(['k1']) data.drop_duplicates(['k1'], keep='last') # False,删掉所有重复值 data.drop_duplicates(['k1', 'k2'], keep=False)
obj = pd.Series(range(5), index = ['a','a','b','b','c']) obj['a'] obj[obj.duplicated()] obj[~(obj.index.duplicated())] # 查询不重复索引对应的值
检测和过滤异常值(了解)
过滤或变换异常值(outlier)在很大程度上就是运用数组运算
例子:一个含有正态分布数据的DataFrame
data = pd.DataFrame(np.random.randn(1000, 4)) data[0:3] data[2][(data[2]>3) | (data[2]<-3)] data[2][np.abs(data[2])>3] # 找出全部绝对值大于3的值所在的行 data[np.abs(data)>3].dropna(how='all') data[np.abs(data) > 3] data[np.abs(data) > 3].any(axis=1) #前面的条件只要有一个生效就是true,一个没有就是False data[data[np.abs(data) > 3].any(axis=1)] a = np.array([3, -4, 7, -100]) np.sign(a) # 判断数据正负,正数1,负数-1,生成一个对应数据的1,-1数据 # 将数据范围限制在3到-3之间(大于3的改为3,小于-3的改为-3) np.sign(data) data[np.abs(data) > 3] = np.sign(data) * 3