我有一个数据框架,其中包含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 ...
您是否考虑过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)
您可以做这样的事情。可以更改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