Pandas:用按时间段分组的中值替换基于异常值的值



我有一个每小时财务估值的Panda DataFrame,其中包含一些异常值。异常值已经被计算出来并标记在数据帧的一列中。

因此,数据帧看起来像这样,每个资产每天有24个唯一的条目("小时"列中日期后面的整数是计算"值"的一天中的小时(:

异常值no是nono无是
资产 小时
AAAA 5.1
BBBB 7.2 1/1/21 1
CCCC 9999 1/1/21 1
AAAA 5.1 1/1/21 2
BBBB 7.2 1/21 2
CCCC 15.0
AAAA 5.3 1/2/21 1
BBBB 9999 1/2/21 1
CCCC 15.6
AAAA 8.1 9/1/21 20
BBBB 9.5 21 20年9月1日
CCCC 9999 9/1/21 20

例如,这种方法首先通过从1/1/21 1中提取1/1/21来创建一列新的日期。然后使用新的dayasset列,它计算fill_vals,这是非异常值的日/资产中值。最后,它使用这些值来填充异常值

import pandas as pd
#Reading in part of your table
df = pd.DataFrame({
'asset': ['AAAA', 'BBBB', 'CCCC', 'AAAA', 'BBBB', 'CCCC'],
'value': [5.1, 7.2, 9999.0, 5.1, 7.2, 15.0],
'hour': ['1/1/21 1','1/1/21 1','1/1/21 1','1/1/21 2','1/1/21 2','1/1/21 2'],
'outlier?': ['no', 'no', 'yes', 'no', 'no', 'no']
})
#Create a new column of the day
df['day'] = df['hour'].str.split(' ').str[0]
fill_vals = df[df['outlier?'].eq('no')].groupby(['asset','day'])['value'].median()
#Reindex the table by asset/day, fill in the outliers, then reset the index
df = df.set_index(['asset','day'])
df.loc[df['outlier?'].eq('yes'),'value'] = fill_vals
df = df.reset_index()
df
# If you want a boolean, use a boolean.
df['outlier?'] = df['outlier?'].replace(['yes', 'no'], [True, False])
# NaN your outliers:
df.loc[df['outlier?'], 'value'] = np.nan
# Fix your Date Column:
df[['date', 'hour']] = df.hour.str.split(expand=True)
df.date = pd.to_datetime(df.date)
df.hour = pd.to_timedelta(df.hour.astype(int), unit='h')
df.date += df.hour
df = df.drop('hour', axis=1)
# Fill NaN values by asset and date:
df['value'] = df.groupby(['asset', df.date.dt.date])['value'].apply(lambda x: x.fillna(x.median()))
print(df)

输出:

asset  value  outlier?                date
0  AAAA    5.1     False 2021-01-01 01:00:00
1  BBBB    7.2     False 2021-01-01 01:00:00
2  CCCC   15.0      True 2021-01-01 01:00:00
3  AAAA    5.1     False 2021-01-01 02:00:00
4  BBBB    7.2     False 2021-01-01 02:00:00
5  CCCC   15.0     False 2021-01-01 02:00:00

最新更新