第七课: - 计算异常值的方法
第 7 课
异常值
Pandas提供了大量与数据探索相关的函数。这些统计特征函数能反映出数据的整体分布,主要作为Pandas的对象DataFrame或Series的方法出现。
sum():计算数据样本的总和(按列计算)
mean():计算数据样本的算术平均数
var():计算数据样本的方差
std():计算数据样本的标准差
corr():计算数据样本的Spearman(Pearson)相关系数矩阵
cov():计算数据样本的协方差矩阵
skew():样本值的偏度(三阶矩)
kurt():样本值的峰度(四阶矩)
describe():给出样本的基本描述(基本统计量如均值、标准差等)
In [1]:
import pandas as pd
import sys
In [2]:
print('Python version ' + sys.version)
print('Pandas version ' + pd.__version__)
In [3]:
# 创建一个以日期为索引的数据帧
States = ['NY', 'NY', 'NY', 'NY', 'FL', 'FL', 'GA', 'GA', 'FL', 'FL']
data = [1.0, 2, 3, 4, 5, 6, 7, 8, 9, 10]
idx = pd.date_range('1/1/2012', periods=10, freq='MS')
df1 = pd.DataFrame(data, index=idx, columns=['Revenue'])
df1['State'] = States
#创建第二个数据帧
data2 = [10.0, 10.0, 9, 9, 8, 8, 7, 7, 6, 6]
idx2 = pd.date_range('1/1/2013', periods=10, freq='MS')
df2 = pd.DataFrame(data2, index=idx2, columns=['Revenue']) df2['State'] = States
请参考pandas中时间序列——date_range函数
In [4]:
# 合并数据帧
df = pd.concat([df1,df2])
df
Out[4]:
计算异常值的方法
注意:平均偏差和标准偏差仅适用于高斯分布。
In [5]:
# 方法 1
# 创建df的一个拷贝
newdf = df.copy()
newdf['x-Mean'] = abs(newdf['Revenue'] - newdf['Revenue'].mean())
newdf['1.96*std'] = 1.96*newdf['Revenue'].std()
newdf['Outlier'] = abs(newdf['Revenue'] - newdf['Revenue'].mean()) > 1.96*newdf['Revenue'].std()
newdf
Out[5]:
In [6]:
# 方法 2
# 按项分组
#创建df的一个拷贝
newdf = df.copy() State = newdf.groupby('State') newdf['Outlier'] = State.transform( lambda x: abs(x-x.mean()) > 1.96*x.std() ) newdf['x-Mean'] = State.transform( lambda x: abs(x-x.mean()) ) newdf['1.96*std'] = State.transform( lambda x: 1.96*x.std() ) newdf
Out[6]:
In [7]:
# Method 2
# Group by multiple items
# make a copy of original df
newdf = df.copy()
StateMonth = newdf.groupby(['State', lambda x: x.month])
newdf['Outlier'] = StateMonth.transform( lambda x: abs(x-x.mean()) > 1.96*x.std() )
newdf['x-Mean'] = StateMonth.transform( lambda x: abs(x-x.mean()) )
newdf['1.96*std'] = StateMonth.transform( lambda x: 1.96*x.std() )
newdf
Out[7]:
In [8]:
# Method 3
# Group by item
# make a copy of original df
newdf = df.copy()
State = newdf.groupby('State')
def s(group):
group['x-Mean'] = abs(group['Revenue'] - group['Revenue'].mean())
group['1.96*std'] = 1.96*group['Revenue'].std()
group['Outlier'] = abs(group['Revenue'] - group['Revenue'].mean()) > 1.96*group['Revenue'].std()
return group
Newdf2 = State.apply(s)
Newdf2
Out[8]:
In [9]:
# Method 3
# Group by multiple items
# make a copy of original df
newdf = df.copy()
StateMonth = newdf.groupby(['State', lambda x: x.month])
def s(group):
group['x-Mean'] = abs(group['Revenue'] - group['Revenue'].mean())
group['1.96*std'] = 1.96*group['Revenue'].std()
group['Outlier'] = abs(group['Revenue'] - group['Revenue'].mean()) > 1.96*group['Revenue'].std()
return group
Newdf2 = StateMonth.apply(s)
Newdf2
Out[9]:
假设一个非高斯分布(如果你绘制它,它看起来不像正态分布)
In [10]:
# make a copy of original df
newdf = df.copy()
State = newdf.groupby('State')
newdf['Lower'] = State['Revenue'].transform( lambda x: x.quantile(q=.25) - (1.5*(x.quantile(q=.75)-x.quantile(q=.25))) )
newdf['Upper'] = State['Revenue'].transform( lambda x: x.quantile(q=.75) + (1.5*(x.quantile(q=.75)-x.quantile(q=.25))) )
newdf['Outlier'] = (newdf['Revenue'] < newdf['Lower']) | (newdf['Revenue'] > newdf['Upper'])
newdf
Out[10]:
This tutorial wasrewrited by CDS