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

2024-05-16 22:50:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据框,上面显示了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   ...

Tags: 数据iddf地方情况nan建模正确处理
2条回答

你考虑过{a1}吗?

例如:

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

相关问题 更多 >