删除异常值以通过箱线图计算 series/dataframe 的平均值?
Removing outliers to calculate mean of a series/dataframe via boxplots?
我正在尝试计算没有异常值的数据框中每一列(系列)的平均值。我使用 seaborn 的箱线图来完成这项任务:
plt.figure(figsize=(50, 10),dpi=200)
sns.boxplot(x='Unit_Code',y='Leadtime',hue='Has_Weekend?',data=df ,palette='winter')
plt.xticks(rotation=90);
这就是我得到的:
plot1
我真的很想得到没有异常值的每个单位(x 轴)的平均值。这背后的合理性,如果我错了请纠正我,我想得到这个特征的平均值,没有异常值,因为
他们扭曲了它。
谢谢!
可以通过多种方式移除异常值。此示例使用 z-score 方法移除异常值。
一旦异常值被移除,计算平均值就像在 DataFrame 的每一列上调用 .mean()
函数或使用 .describe()
函数一样简单。
无需过多赘述,z-score 是一种确定某个值与平均值之间有多少标准差的方法。这真的很简单,就是每个值减去平均值,除以数据集的标准差。一般来说,对于接近均值的正态分布数据,z 分数 3 可以用作过滤器 - 这在下面的案例中得到了证明。
This article might be of interest, regarding the detection and removal of outliers.
计算 z 得分的一种简单方法可能是使用 scipy.stats
模块,以及 docs referenced here.
对于这个例子,我合成了一个数据集,可以在这个答案的底部找到。此外,由于我对 plotly 比 seaborn 更熟悉,所以我选择使用 plotly 进行绘图。
让我们继续吧...
之前:
此示例代码与问题无关,只是绘制代码。
l = {'title': 'Boxplot - With Outliers'}
t = []
t.append({'y': df['AZGD01'], 'type': 'box', 'name': 'AZGD01'})
t.append({'y': df['AZPH01'], 'type': 'box', 'name': 'AZPH01'})
t.append({'y': df['AZPV01'], 'type': 'box', 'name': 'AZPV01'})
iplot({'data': t, 'layout': l})
输出:
使用 z 分数过滤:
这显示了如何在 DataFrame 的每一列上计算 z-score 的示例,其中 filtered 值存储到第二个 DataFrame。
步骤:
- 迭代每一列
- 使用
scipy.stats.zscore()
函数计算 z 分数
- 过滤以仅保留 z 得分 > 3 的记录
- 存储到新的 DataFrame
示例:
from scipy import stats
df_z = pd.DataFrame()
for c in df:
# Calculate z-score for each column.
z = stats.zscore(df[c])
# Filter to keep records with z-scores < 3.
df_z[f'{c}_z'] = df.loc[z<3, c]
之后:
同样,只是不相关的绘图代码 - 但请注意第二个(过滤后的)DataFrame 用于绘图。
l = {'title': 'Boxlot - Outliers (> 3 std) Removed'}
t = []
t.append({'y': df_z['AZGD01_z'], 'type': 'box', 'name': 'AZGD01'})
t.append({'y': df_z['AZPH01_z'], 'type': 'box', 'name': 'AZPH01'})
t.append({'y': df_z['AZPV01_z'], 'type': 'box', 'name': 'AZPV01'})
iplot({'data': t, 'layout': l})
输出:
示例数据集构建:
下面是更不相关的代码,用于构建示例数据集。
import numpy as np
import pandas as pd
from plotly.offline import iplot
from sklearn.preprocessing import MinMaxScaler
mms = MinMaxScaler((0, 100))
np.random.seed(7)
vals1 = mms.fit_transform(np.random.randn(1000).reshape(-1, 1)).ravel()
np.random.seed(3)
vals2 = mms.fit_transform(np.random.randn(1000).reshape(-1, 1)).ravel()
np.random.seed(73)
vals3 = mms.fit_transform(np.random.randn(1000).reshape(-1, 1)).ravel()
outl1 = np.arange(150, 200, 10)
outl2 = np.arange(200, 250, 10)
outl3 = np.arange(250, 300, 10)
data1 = np.concatenate([vals1, outl1])
data2 = np.concatenate([vals2, outl2])
data3 = np.concatenate([vals3, outl3])
df = pd.DataFrame({'AZGD01': data1, 'AZPH01': data2, 'AZPV01': data3})
我正在尝试计算没有异常值的数据框中每一列(系列)的平均值。我使用 seaborn 的箱线图来完成这项任务:
plt.figure(figsize=(50, 10),dpi=200)
sns.boxplot(x='Unit_Code',y='Leadtime',hue='Has_Weekend?',data=df ,palette='winter')
plt.xticks(rotation=90);
这就是我得到的:
plot1
我真的很想得到没有异常值的每个单位(x 轴)的平均值。这背后的合理性,如果我错了请纠正我,我想得到这个特征的平均值,没有异常值,因为 他们扭曲了它。
谢谢!
可以通过多种方式移除异常值。此示例使用 z-score 方法移除异常值。
一旦异常值被移除,计算平均值就像在 DataFrame 的每一列上调用 .mean()
函数或使用 .describe()
函数一样简单。
无需过多赘述,z-score 是一种确定某个值与平均值之间有多少标准差的方法。这真的很简单,就是每个值减去平均值,除以数据集的标准差。一般来说,对于接近均值的正态分布数据,z 分数 3 可以用作过滤器 - 这在下面的案例中得到了证明。
This article might be of interest, regarding the detection and removal of outliers.
计算 z 得分的一种简单方法可能是使用 scipy.stats
模块,以及 docs referenced here.
对于这个例子,我合成了一个数据集,可以在这个答案的底部找到。此外,由于我对 plotly 比 seaborn 更熟悉,所以我选择使用 plotly 进行绘图。
让我们继续吧...
之前:
此示例代码与问题无关,只是绘制代码。
l = {'title': 'Boxplot - With Outliers'}
t = []
t.append({'y': df['AZGD01'], 'type': 'box', 'name': 'AZGD01'})
t.append({'y': df['AZPH01'], 'type': 'box', 'name': 'AZPH01'})
t.append({'y': df['AZPV01'], 'type': 'box', 'name': 'AZPV01'})
iplot({'data': t, 'layout': l})
输出:
使用 z 分数过滤:
这显示了如何在 DataFrame 的每一列上计算 z-score 的示例,其中 filtered 值存储到第二个 DataFrame。
步骤:
- 迭代每一列
- 使用
scipy.stats.zscore()
函数计算 z 分数 - 过滤以仅保留 z 得分 > 3 的记录
- 存储到新的 DataFrame
示例:
from scipy import stats
df_z = pd.DataFrame()
for c in df:
# Calculate z-score for each column.
z = stats.zscore(df[c])
# Filter to keep records with z-scores < 3.
df_z[f'{c}_z'] = df.loc[z<3, c]
之后:
同样,只是不相关的绘图代码 - 但请注意第二个(过滤后的)DataFrame 用于绘图。
l = {'title': 'Boxlot - Outliers (> 3 std) Removed'}
t = []
t.append({'y': df_z['AZGD01_z'], 'type': 'box', 'name': 'AZGD01'})
t.append({'y': df_z['AZPH01_z'], 'type': 'box', 'name': 'AZPH01'})
t.append({'y': df_z['AZPV01_z'], 'type': 'box', 'name': 'AZPV01'})
iplot({'data': t, 'layout': l})
输出:
示例数据集构建:
下面是更不相关的代码,用于构建示例数据集。
import numpy as np
import pandas as pd
from plotly.offline import iplot
from sklearn.preprocessing import MinMaxScaler
mms = MinMaxScaler((0, 100))
np.random.seed(7)
vals1 = mms.fit_transform(np.random.randn(1000).reshape(-1, 1)).ravel()
np.random.seed(3)
vals2 = mms.fit_transform(np.random.randn(1000).reshape(-1, 1)).ravel()
np.random.seed(73)
vals3 = mms.fit_transform(np.random.randn(1000).reshape(-1, 1)).ravel()
outl1 = np.arange(150, 200, 10)
outl2 = np.arange(200, 250, 10)
outl3 = np.arange(250, 300, 10)
data1 = np.concatenate([vals1, outl1])
data2 = np.concatenate([vals2, outl2])
data3 = np.concatenate([vals3, outl3])
df = pd.DataFrame({'AZGD01': data1, 'AZPH01': data2, 'AZPV01': data3})