我需要过滤数据集中的异常值。在我的应用程序中,用列中的先前值替换异常值最有意义。
使用可用的pandas
工具很难做到这一点(主要与切片上的副本或设置为NaN
时发生的类型转换有关)。
是否有一种快速和/或内存有效的方法来做到这一点? (请参阅下面有关我当前使用的解决方案的回答,该解决方案也有局限性。)
一个简单的例子:
>>> import pandas as pd
>>> df = pd.DataFrame({'A':[1,2,3,4,1000,6,7,8],'B':list('abcdefgh')})
>>> df
A B
0 1 a
1 2 b
2 3 c
3 4 d
4 1000 e # '1000 e' --> '4 e'
5 6 f
6 7 g
7 8 h
答案 0 :(得分:1)
您可以简单地掩盖阈值上的值并使用ffill
:
df.assign(A=df.A.mask(df.A.gt(10)).ffill())
A B
0 1.0 a
1 2.0 b
2 3.0 c
3 4.0 d
4 4.0 e
5 6.0 f
6 7.0 g
7 8.0 h
使用mask
而不是使用shift
之类的东西是必要的,因为它可以保证在先前值也高于阈值的情况下输出非离群值。
答案 1 :(得分:0)
我通过首先转换为pandas
数组,在那里进行操作,然后重新插入列,来规避了numpy
副本和切片的某些问题。我不确定,但是据我所知,一旦将数据类型放回到pandas.DataFrame
中,数据类型就相同。
def df_replace_with_previous(df,col,maskfunc,inplace=False):
arr = np.array(df[col])
mask = maskfunc(arr)
arr[ mask ] = arr[ list(mask)[1:]+[False] ]
if inplace:
df[col] = arr
return
else:
df2 = df.copy()
df2[col] = arr
return df2
这将创建一个掩码,将其向下移动一个,以使True
值指向上一个条目,并更新数组。当然,如果有多个相邻的异常值(如果有N个连续的异常值,则需要N次),这将需要递归运行。
在OP中给出的用法:
df_replace_with_previous(df,'A',lambda x:x>10,False)