在计算数据均值时有什么好的方法可以处理异常值?

问题描述 投票:0回答:2

我有一个数据框架,其中包含5年以上建筑物的年度能耗。为了在数据建模方面有代表性的年度能耗,我必须取这些数据的平均值。由于数据可能包含异常值,因此我想正确处理异常值(但要保留尽可能多的正确数据)。 (df可以包含空单元格(如果必须在某个地方进行加权决策,则较之几年,近几年的重要性要大))

在计算数据平均值时,有什么好的方法可以处理异常值?

我考虑过:-计算5个数据列的平均值(y_2010-y_2014),然后将所有5个数据点与该平均值进行比较。如果有例如> 20%时,此案例将被删除,由于该ID的数据存在很大差异,因此无法用于进一步分析。 (通常,除非对建筑物进行了改建,否则5年内的能源数据应大致相同,但大多数建筑物没有。)-用滚动的方法做一些事情,以达到适当的平均建筑能耗指标-...

df的示例:

   ID  y_2010   y_2011   y_2012  y_2013  y_2014  mean
21524   22631    21954    22314   22032   21843   ...
28965   27456    29654    28159   28654   27345   ...
10236   32165      NaN    31678   31895   32459   ...
89754   87621    86542    87542   88456   86961   ...
56457   58951    57486     2000       0       0   ...
25984   24587    25478      NaN   24896   25461   ...
python pandas mean outliers
2个回答
0
投票

您是否考虑过trimmed / truncated mean

示例:

import pandas as pd
from scipy import stats

# Trim 20% on both ends
stats.trim_mean(df['y_2010'], proportiontocut=0.2)

0
投票

您可以做这样的事情。可以更改reject_outliers()m参数以获得所需的灵敏度。降低m会删除更多的值,而提高m会删除更少的值。

def reject_outliers(df_median, series, m):
    diff = np.abs(series - df_median)
    mdev = np.median(diff)
    s = diff / mdev if mdev else np.nan

    return series[s < m]


df = pd.read_clipboard(dtype=float)

print(df)
    ID      y_2010  y_2011  y_2012  y_2013  y_2014
0   21524.0 22631.0 21954.0 22314.0 22032.0 21843.0
1   28965.0 27456.0 29654.0 28159.0 28654.0 27345.0
2   10236.0 32165.0 NaN     31678.0 31895.0 32459.0
3   89754.0 87621.0 86542.0 87542.0 88456.0 86961.0
4   56457.0 58951.0 57486.0 2000.0  0.0     0.0
5   25984.0 24587.0 25478.0 NaN     24896.0 25461.0

这里我们进行切片以获取ID以外的所有列,并获取它们的中位数。使用np.nanmedian可以使我们具有nan值。

df_slice = df.iloc[:, 1:]
df_median = np.nanmedian(df_slice.values)

我们需要用0.0填充nan值,以使remove_outliers()正常工作。

df = df.fillna(0.0)

我们在非ID列上运行函数。

for col in df_slice.columns:
    df[col] = reject_outliers(est_median, df[col], m=3)

现在我们将0.0转换为np.nan。

df.replace(0.0, np.nan, inplace=True)

并将ID列转换回int dtype。不能完全确定这是否是您所需要的,但应根据需要轻松进行修改。 FWIW,如示例所示,pandas不允许int dtype列中使用nan值。

df['ID'] = df['ID'].astype(int)

print(df)


      ID    y_2010  y_2011  y_2012  y_2013  y_2014
0   21524   22631.0 21954.0 22314.0 22032.0 21843.0
1   28965   27456.0 29654.0 28159.0 28654.0 27345.0
2   10236   32165.0 NaN     31678.0 31895.0 32459.0
3   89754   NaN     NaN     NaN     NaN     NaN
4   56457   NaN     57486.0 2000.0  NaN     NaN
5   25984   24587.0 25478.0 NaN     24896.0 25461.0
© www.soinside.com 2019 - 2024. All rights reserved.