开发者学堂课程【高校精品课-华东师范大学 - Python 数据科学基础与实践:Pandas 数据预处理-下】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1067/detail/15390
Pandas 数据预处理-下
内容简介:
一、Discretization and Binning(离散化和分箱)
二、Detecting and Filtering Outliers(检测和过滤异常值)
三、Permutation and Random Sampling(排列和随机采样)
一、Discretization and Binning(离散化和分箱)
连续型数据经常被离散化或分散成bins(分箱)来分析。假设你有一组数据,你想把人分散到不同的年龄组里:
ages =[20,22,25,27,21,23,37,31,61,45,41,32]
我们把这些分到四个bin里,1925,2635,36~60,>60。可以用pandas里的cut:bins =[18,25,35,60,100]
//设时间的值为18到25,25到35,35到60,60到100cats = pd.cut(ages, bins)
cats
[(18,25],(18, 25],(18, 25],(25, 35],(18, 25],…,(25,35],(60,100],(35, 60],(35, 60],(25,35]]
Length:12
Categories (4, interval[int64]):[(18,25] <(25,35] <(35,60]<(68,100]
]//显示有多少类别,每个区间就是一个类别,注意括号
返回的是一个特殊的Categorical object。
我们看到的结果描述了pandas.cut如何得到bins。可以看作是一个string数组用来表示bin的名字,它内部包含了一个categories数组,用来记录不同类别的名字,并伴有表示ages的label(可以通过codes属性查看):cats.codes
array ([0, 0, 0, 1, 0, 0, 2, 1, 3, 2, 2, 1], dtype = int8)/
/区间编号cats . categories
Interval Index ([(18, 25], (25, 35],(35, 60],(60,100]],
closed= ‘right’,/
/每一个区间的右边是对的,包括的
dtype= ‘interval[int64] ‘)
pd . value _ counts (cats (18,25] 5
(35,60] 3
(25,35] 3
(60,100] 1
dtype:int64)/
/分箱后可以和value _ counts结合起来,还可以统计每一个区间的样本数量
这里pd . value _ counts (cats) 是pandas . cut 后 bin 的数量。
这里我们注意一下区间。括号表示不包含,方括号表示包含。你可以自己设定哪一边关闭(right = False):
pd . cut (ages,[18,26,36,61,100],right=False)
[[18, 26),[18, 26),[18, 26),[26,36),[18, 26),.., [26, 36),[61,100),[36, 61),[36, 61),[26, 36)]
Length:12
Categories (4, interval[int64]):[[18, 26) <[26, 36)<[36,61)<[61,100)]
// right = False的例子
你也可以用一个 list 或数组给 labels 选项来设定 bin 的名字:group_names =[‘Youth’,‘YoungAdult’, MiddleAged’,’Senior’]
pd . cut(ages, bins , labels = group _ names)
[Youth, Youth, Youth, YoungAdult, Youth,.., YoungAdult, Senior, MiddleAged, MiddleAged, YoungAdult]
Length:12
Categories (4, object): [Youth < YoungAdult < MiddleAged < Senior]
如果你只是给一个bins的数量来cut,而不是自己设定每个bind的范围,cut会根据最大值和最小值来计算等长的bins。比如下面我们想要做一个均匀分布的四个bins:
data = np.random.rand(20)
//创建20个随机数pd.cut(data, 4, precision=2)
//四个区间,精度为二[(0.041, 0.26],(0.26, 0.47],(0.26, 0.47],(0.47, 0.69],(0.26,0.47],…,(0.69,0.9], (0.26, 0.47],(0.26, 0.47],(0.69,0.9],(0.041,0.26]]
Length:20
//等区间划分,每个区间是五个值,一共二十个
Categories(4,interval[float64]
:[(0.041, 0.26]<(0.26,0.47]<(0.47, 0.69]<(0.69, 0.9]]
precision=2选项表示精确到小数点后两位。
一个近似的函数,qcut,会按照数据的分位数来分箱。取决于数据的分布,用cut通常不能保证每一个bin有一个相同数量的数据点。而qcut是按百分比来切的,所以可以得到等数量的bins:data = np.random.randn(1000) # Normally distributed
cats = pd.qcut(data, 4)#Cut into quartiles
cats
[(-0.0014, 0.697],(-0.69,-0.8014],(-3.226,-0.69],(0.697,3.253],(-3.226,-0.69],…,(-0.69,-0.0014],(-0.0014, 0.697],(-3.226, -0.69], (-0.69, -0.0014], (-3.226, -0.69]]
Length:1000
Categories (4,interval[float64]): [(-3.226, -0.69]<(-0.69,-0.0014]<(- 0.0014, 0.697]<(0.697, 3.253]]
pd.value_counts(cats)I
(0.661,3.265] 250
(-0.0107,0.661 ] 250
(-0.652,-0.0107] 250
(-3.0309999999999997,-0.652] 250
//每个区间都是250个dtype:int64
类似的,在cut中我们可以自己指定百分比:
cats2= pd.cut (data,o, 0.1,0.5,0.9,1.])
#累进的百分比cats2
[NaN, NaN, (0.1, 0.5], (0.0, 0.1], (0.0, 0.1],.., (0.1, 0.5], NaN, (0.1, 0.5],NaN, NaN]
Length:1000
Categories (4, interval[float64]): [(0.0, 0.1]<(0.1, 0.5]<(0.5, 0.9]<(0.9, 1.0]]
pd.value_counts(cats2)
(0.1,0.5] 159
(0.5,0.9] 111
(0.0.0.1] 39
运行结果如下:
cats2 = pd.cut(data, [0, 0.1, 0.5, 0.9,1.])
#累进的百分比cats2
[(0.5,0.9],NaN, NaN, (0.5, 0.9], NaN, ..., NaN, (0.5, 0.9],NaN,NaN, NaN]
Length:1000
Categories (4, interval[float64]):[(0.0, 0.1]<(0.1, 0.5]<(0.5,0.9]<(0.9, 1.0] ]
pd.value_counts(cats2)
(0.1,0.5] 141
(0.5,0.9] 130
(0.0,0.1] 42
(0.9,1.0] 23
//按照累进的百分比来做的,可以根据数据来对照一下dtype:int64
在之后的章节我们还会用到cut和qcut,这些离散函数对于量化和群聚分析很有用。
二、Detecting and Filtering Outliers(检测和过滤异常值)
过滤或转换异常值是数组操作的一个重头戏,经常会用的,且易于理解。下面的DataFrame有正态分布的数据:
data = pd.DataFrame(np.random.randn(1000, 4))
data.describe()
//这是1000行4列的随机数0 1 2 3
count 1000.000000 1000.000000 1000.000000 1000.000000
mean -0.002456 -0.013464 -0.018596 0.009185
std 1.010189 1.009359 0.956202 0.983509
min -3.306016 -3.234603 -2.841502 -3.160032
25% -0.700614 -0.681737 -0.685092 -0.642624
50% 0.007757 -0.016974 -0.022181 0.001638
75% 0.661273 0.677564 0.650797 0.667137
max 3.513155 3.015989 3.702078 2.813043
假设我们想要找一个列中,绝对值大于3的数字:
data.head()
0 1 2 3
0 1.001331 0.141444 -0.658976 -0.559929
1 1.404844 1.806265 -0.022745 0.758905
2 0.360715 -2.228443 -1.331441 1.197109
3 -0.295798 1.059002 -0.203292 -0.974873
4 -0.642556 0.105651 -1.058893 -0.461502
col = data[2]
col.head()
运行结果如下:
data.head()
0 1 2 3
0 1.549775 -1.632323 0.026592 -0.919571
1 -0.985463 0.715839 -0.010901 1.933010
2 0.178723 -0.503543 -0.111506 -2.373872
3 0.808442 -0.146981 1.235779 -0.435777
4 -0.260666 -1.439726 0.867837 1.082157
col = data[2]
col.head()
看一下五条记录
看一下第二列的数据,也就是0,1,2,看前五条
0 0.026592
1 -0.010901
2 -0.111506
3 1.235779
4 0.867837
Name:2, dtype:float64
col[np.abs(col) >3]
413 3.702078
Name:2, dtype:float64
运行结果如下:
col[np.abs(col) > 3]
145 3.095765
491 -3.076750
833 3.769872
Name:2,dtype:float64
选中所有绝对值大于3的行,可以用any方法在一个boolean DataFrame上:
下面的内容就是相似的,大家可以操作看一下。
三、Permutation and Random Sampling(排列和随机采样)
排列(随机排序)一个series或DataFrame中的row,用numpy.random.permutation函数很容易就能做到。调用permutation的时候设定好你想要进行排列的axis,会产生一个整数数组表示新的顺序:
df = pd.DataFrame(np.arange(5 * 4).reshape((5, 4)))
df//创建一个5行4列数组
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
3 12 13 14 15
4 16 17 18 19
sampler = np.random.permutation(5)
sampler// 用permutation,给一个参数5,随机排序,相当于随机采样器array([4, 3, 2, 0,1]
运行结果如下:
array([0,3,1,2,4]//产生一个新的顺序
这个数组能被用在基于iloc上的indexing或take函数:
后面还有一些其他的方法,大家可以看一下
最后Computing Indicator/Dummy Variables(计算指示器/虚拟变量)加了**,稍微有一些复杂可以研究一下。