pandas模块-数据拆分-异常值筛选-过滤
导入模块:
import numpy as npimport pandas as pdfrom pandas import Series,DataFramefrom numpy import nan as NA# matplotlib做图模块import matplotlib.pyplot as plt# 处理中文正常显示plt.rcParams[\'font.sans-serif\'] = [\'Microsoft YaHei\']
1.数据拆分(分割,切割)
(1)pd.cut() 根据区间,求数量。 结合 value_counts()
pd.cut(
x, //被分割的对象
bins, // 分箱可以是数字也可以是list-like的分箱
right: bool = True, //默认右边闭合
labels=None, //给每个区间取个别名
retbins: bool = False, //True ,返回一个区间数组
precision: int = 3, // 默认精确到小数点后3位
include_lowest: bool = False, //分割区间默认不包含最小值,True则包含
duplicates: str = ‘raise’,
ordered: bool = True,
)
准备一个数据 ,如 一堆年龄
bins = [18,40,60,100,801]ages = [16,20,24,28,30,38,40,44,47,54,56,61,66,77,88,99,800]
(1.1)用value_counts
Series(ages).value_counts(bins=bins)
(1.2)用pd.cut()
pd.cut(ages,bins=bins)
pd.cut和value_counts()结合使用,dropna=True默认不保留NaN
pd.cut(ages,bins=bins).value_counts(dropna=False)
right参数,默认bins区间右闭合
pd.cut(ages,bins=bins,right=False)
labels 参数 ,给每个区间取个别名(好处是用值统计显示更直观)
pd.cut(ages,bins=bins,right=True ,labels=[\'青年\',\'中年\',\'老年\',\'神仙\']).value_counts()
retbins参数。默认True ,返回一个区间数组
使用随机数进行分割,先创建一个随机数数组
# 生成有小数的数组arr = np.random.randn(20)arr
precision: int = 3, 默认精确到小数点后3位
pd.cut(arr,4 ,precision=3)
include_lowest: bool = False, 分割区间默认不包含最小值
pd.cut(ages,bins ,include_lowest=True)
duplicates: str = ‘raise’ / ‘drop’:造一个特殊数据来分割
arr2 = [1,2,3,4,5]*4pd.cut(arr2 ,bins = [1,2,2,3,4,5] ,duplicates=\'drop\',include_lowest=True)
(2)pd.qcut() 根据数量,求区间。 结合 value_counts()
pd.qcut(
x,
q, // 可以是整数等分,也可以是 [0 , 0.1 ,0.3 ,0.6 ,1] 比例
labels=None,
retbins: bool = False,
precision: int = 3,
duplicates: str = ‘raise’,
)
先创建随机100个人的年龄
array=np.random.randint(0,101,100)array
q可以用整数等分
pd.qcut(array,4)
pd.qcut(array,4).value_counts()
q也可以用比例来分
pd.qcut(array,q=[0 ,0.1,0.3,0.6 ,1 ] )
pd.qcut(array,q=[0 ,0.1,0.3,0.6 ,1 ] ).value_counts()
retbins参数,返回一个区间数组
pd.qcut(array,4 ,retbins=True)
# 取最后一行的区间数组pd.qcut(array,4 ,retbins=True)[-1]
2.检查和过滤异常值
(1)筛选
先创建一个数组,假设 我们统计马拉松选手的年龄 18-60
age = Series(np.random.randint(10,70,3000))age
找出年龄在18-60之间有多少人
用匿名函数判断
age.apply(lambda x:x if 18<=x<=60 else NA).count()
用值计数bins区间求
age.value_counts(bins=[18,60])
用刚学的数据拆分来求
pd.cut(age,bins=[18,60],include_lowest=True).value_counts()
假设参赛人数就是3000人,把小于18的全部替换成18 ,大于60替换成60
age2=age.copy()
方法1:用函数判断
def filterNum(x):if x<=18:return 18elif x>=60:return 60else:return xage2.apply(filterNum)
方法2:用匿名函数
age2.apply(lambda x:18 if x<=18 else x).apply(lambda x:60 if x>=60 else x)
方法3:
age2[age2<18]=18age2[age2>60]=60age2
方法4:用replace
age.replace(np.arange(10,18),18).replace(np.arange(60,70),60)
(2)过滤
创建一个数据
data = DataFrame(np.random.randn(1000,4) ,columns=list(\'ABCD\'))data
假设绝对值 大于3 的都是 异常值
方法1:取出一列的数据
data.C[data.C.abs()>3]
方法2:可以直接用 dataframe 与 3 比较
# ABCD列都有 True,所以每列都有异常值np.abs(data)>3.any(axis=0)
data[ (np.abs(data)>3).any(axis=1) ]
方法3:处理所有值,将绝对值大于3的变成 +3 或 -3 。通过np.sign( )获取符号位
result = data.applymap(lambda x:np.sign(x)*3 if np.abs(x)>3 else x)result
如果某行有 绝对值大于3 的,全部换成 3 或 -3
data[ (np.abs(data)>3).any(axis=1) ]
每个数的符号位 乘以 3
np.sign(data)*3
对筛选的数据进行 替换 ,会只替换掉那些 行索引 匹配的值
data[ (np.abs(data)>3).any(axis=1) ] = np.sign(data)*3data.loc[512:515]
3.
Series.apply( 某个函数 )
DataFrame.applymap( 某个函数 )
都是对单个值处理的