数据清洗
import pandas as pd
data = pd.read_csv('missing_data.csv')
print('是否有空数据',data.isnull().any())
print(data.isnull().all())
print('统计空数据')
print(data.isnull().sum())
是否有空数控 235.8333 True
324.0343 True
478.3231 True
dtype: bool
235.8333 False
324.0343 False
478.3231 False
dtype: bool
统计空数据
235.8333 2
324.0343 4
478.3231 4
dtype: int64
固定填充空数据fillna(value=None)
pandas.DataFrame.fillna(value=None, #接收scalar,dict,Series或者DataFrame。表示用来替换缺失值的值。无默认。
method=None,#接收特定string。backfill或bfill表示使用下一个非缺失值填补缺失值。pad或ffill表示使用上一个非缺失值填补缺失值。默认为None。
axis=None, #接收0或1。表示轴向。默认为1。
inplace=False,#接收boolean。表示是否在原表上进行操作。默认为False。
limit=None#接收int。表示填补缺失值个数上限,超过则不进行填补。默认为None
)
#固定值填充
dt1 = data.fillna(value='23')
print(dt1.head())
#均值填充
dt2 = data.fillna(value=data.mean())
print('均值填充')
print(dt2.head())
235.8333 324.0343 478.3231
0 236.271 325.638 515.456
1 238.052 328.09 517.091
2 235.906 23 514.89
3 236.76 268.832 23
4 23 404.048 486.091
均值填充
235.8333 324.0343 478.3231
0 236.270800 325.637900 515.456400
1 238.052100 328.089700 517.090900
2 235.906300 366.143263 514.890000
3 236.760400 268.832400 558.625281
4 236.286478 404.048000 486.091200
中位数填充
dr =data.median()
dr
#中位数填充
data.fillna(value=data.median()).head()
235.8333 | 324.0343 | 478.3231 | |
---|---|---|---|
0 | 236.27080 | 325.6379 | 515.4564 |
1 | 238.05210 | 328.0897 | 517.0909 |
2 | 235.90630 | 389.6441 | 514.8900 |
3 | 236.76040 | 268.8324 | 547.3461 |
4 | 235.95315 | 404.0480 | 486.0912 |
众数填充
data['235.8333'].value_counts()
data['235.8333'].value_counts()
237.6042 1
235.2396 1
235.5000 1
237.4167 1
236.0000 1
235.0729 1
235.5313 1
234.4688 1
235.9063 1
236.2708 1
234.5521 1
238.0521 1
235.6354 1
236.9688 1
236.7604 1
238.6563 1
235.4896 1
238.0313 1
Name: 235.8333, dtype: int64
3σ原则
'''
3σ原则又称为拉依达法则。该法则就是先假设一组检测数据只含有随机误差,对原始数据进行计算处理得
到标准差,然后按一定的概率确定一个区间,认为误差超过这个区间的就属于异常值。
μ-3σ,μ+3σ)内,超出这个范围的数据仅占不到0.3%。故根据小概率原
理,可以认为超出3σ的部分数据为异常数据。
'''
import pandas as pd
import numpy as np
#1.定义检测异常函数3σ
#(μ-3σ,μ+3σ)
def f(data):
mean = data.mean()
std = data.std()
bool_idx = (data >(mean-3*std)) & (data < (mean+3*std))
#print(bool_idx)
return bool_idx
detail = pd.read_excel('meal_order_detail.xlsx')
# print(detail.info())
bool_idx = f(detail['amounts'])
print(detail.loc[bool_idx,:].shape)
(2649, 19)
箱线图分析
#2.箱线图
#1.首先求出分位:np.percentile, pandas:quantile
#2.求出IQR
#异常值通常被定义为小于Q1-1.5IQR或大于Q3+1.5IQR的值
list1 = ((detail['amounts'].quantile([0.25,0.75]).values))
Q1 = list1[0]
Q3 = list1[1]
IQR = Q3 - Q1
bool_Idx = (detail['amounts'] > (Q1 - 1.5*IQR)) & (detail['amounts'] < (Q3 + 1.5*IQR))
print(detail.loc[bool_Idx,:].shape)
#np.percentile(0.25,0.75)
(2606, 19)
离差标准化数据
数据的整体分布情况并不会随离差标准化而发生改变,原先取值较大的数据,在做完离差标准化后的值依
旧较大。
Ø 当数据和最小值相等的时候,通过离差标准化可以发现数据变为0。
Ø 若数据极差过大就会出现数据在离差标准化后数据之间的差值非常小的情况。
Ø 同时,还可以看出离差标准化的缺点:若数据集中某个数值很大,则离差标准化的值就会接近于0,并且
相互之间差别不大。若将来遇到超过目前属性[min,max]取值范围的时候,会引起系统出错,这时便需要
重新确定min和max。
import numpy as np
import pandas as pd
#离差标准化[0,1]包含0,1
def min_max(data):
res = (data - data.min())/(data.max() - data.min())
return res
#标准差标准化
def standard(data):
mean = data.mean()
std = data.std()
res = (data - mean)/std
return res
#小数定点标准化
def xiaoshu(data):
k = np.ceil(np.log10(np.abs(data).max()))
res = data/(10 ** k)
return res
arr = np.array([3,6,1,9,10,7,101])
print(min_max(arr))
print(standard(arr))
print(xiaoshu(arr))
[0.02 0.05 0. 0.08 0.09 0.06 1. ]
[-0.49657061 -0.40667421 -0.55650155 -0.3167778 -0.28681234 -0.37670874
2.44004524]
[0.003 0.006 0.001 0.009 0.01 0.007 0.101]
转换数据
#哑变量处理类别数据
pandas.get_dummies(
data ,#接收array、DataFrame或者Series。表示需要哑变量处理的数据。无默认。
prefix ,#接收string、string的列表或者string的dict。表示哑变量化后列名的前缀。默认为None。
prefix_sep,# 接收string。表示前缀的连接符。默认为‘_’。
dummy_na,# 接收boolean。表示是否为Nan值添加一列。默认为False。
columns,#接收类似list的数据。表示DataFrame中需要编码的列名。默认为None,表示对所有object和category类型进行编码。
sparse ,#接收boolean。表示虚拟列是否是稀疏的。默认为False。
drop_first ,#接收boolean。表示是否通过从k个分类级别中删除第一级来获得k-1个分类级别。默认为False。
)
import pandas as pd
import numpy as np
#1.类别型特征连续化
cities = pd.Series(['广州','北京','苏州','杭州','西安'])
print(pd.get_dummies(cities,prefix='城市_'))
城市__北京 城市__广州 城市__杭州 城市__苏州 城市__西安
0 0 1 0 0 0
1 1 0 0 0 0
2 0 0 0 1 0
3 0 0 1 0 0
4 0 0 0 0 1
# 离散化连续型数据
#第一种:等宽
pandas.cut(
x ,#接收数组或Series。代表需要进行离散化处理的数据。无默认。
bins,#接收int,list,array,tuple。若为int,代表离散化后的类别数目;若为序列类型的数据,则表示进行切分的区间,每两个数间隔为一个区间。无默认。
right,# 接收boolean。代表右侧是否为闭区间。默认为True。
labels,# 接收list,array。代表离散化后各个类别的名称。默认为空。
retbins,# 接收boolean。代表是否返回区间标签。默认为False。
precision,# 接收int。显示的标签的精度。默认为3。
)
# 使用等宽法离散化的缺陷为:等宽法离散化对数据分布具有较高要求,若数据分布不均匀,那么各个类的数目
# 也会变得非常不均匀,有些区间包含许多数据,而另外一些区间的数据极少,这会严重损坏所建立的模型。
#2.连续型特征离散化
#第一种:等宽
#连续特征离散化
np.random.seed(1) #设置随机数每次都是一样
scores = np.random.randint(1,100,15) #生成0到100之间的15个整数,当做考试成绩
scores = pd.Series(scores)
# print(scores)
res = pd.cut(scores,bins=4)
print(res)
0 (21.5, 41.0]
1 (1.922, 21.5]
2 (60.5, 80.0]
3 (1.922, 21.5]
4 (60.5, 80.0]
5 (1.922, 21.5]
6 (60.5, 80.0]
7 (60.5, 80.0]
8 (1.922, 21.5]
9 (1.922, 21.5]
10 (60.5, 80.0]
11 (60.5, 80.0]
12 (1.922, 21.5]
13 (21.5, 41.0]
14 (41.0, 60.5]
dtype: category
Categories (4, interval[float64]): [(1.922, 21.5] < (21.5, 41.0] < (41.0, 60.5] < (60.5, 80.0]]
等频法
# 等频法离散化的方法相比较于等宽法离散化而言,避免了类分布不均匀的问题,但同时却也有可能将数值
# 非常接近的两个值分到不同的区间以满足每个区间中固定的数据个数
#第二种:等频划分
#qcut:等频划分,q=整数,代表数据划分区间
# q=[0, .25, .5, .75, 1.](分位数)
res = pd.qcut(scores,q=[0, .25, .5, .75, 1.])
print(res.value_counts())
(72.5, 80.0] 4
(11.5, 38.0] 4
(1.999, 11.5] 4
(38.0, 72.5] 3
dtype: int64