Pandas之数据规整清理

数据规整(数据预处理,数据清洗)

数据规整的一般分类:

  • 清理
  • 转换
  • 合并
  • 重塑

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

 

  

posted @ 2020-08-09 18:31  亚洲哈登  阅读(265)  评论(0编辑  收藏  举报