import pandas as pd
data = {'side':['a', 'a', 'a', 'b', 'a', 'a', 'a', 'b', 'b', 'a'],
'price':[10400, 10400, 10400, 10380, 1041, 10400, 1041, 10400, 10399, 10399],
'b_d100_v':[1, 1, 1, 0.3, 10, 10, 10, 10, 9, 9],
'b_d100_p':[10390, 10391, 10390, 10390, 10390.5, 10385, 10385, 10386, 10387, 10387],
'a_d052_v':[11, 11, 11, 9.3, 0.1, 0.1, 0.1, 0.1, 0.2, 0.3],
'a_d052_p':[10399, 10403, 10400, 10401, 1041, 1041, 10400, 10400, 10402, 10404]
}
df = pd.DataFrame(data, index=[101, 102, 102, 104, 105, 106, 107, 107, 107, 107])
print(df)
side price b_d100_v b_d100_p a_d052_v a_d052_p
101 a 10400 1.0 10390.0 11.0 10399
102 a 10400 1.0 10391.0 11.0 10403
102 a 10400 1.0 10390.0 11.0 10400
104 b 10380 0.3 10390.0 9.3 10401
105 a 1041 10.0 10390.5 0.1 1041 # Row to delete (outlier 1041 on 'price' and 'a_d052_p' columns)
106 a 10400 10.0 10385.0 0.1 1041 # Row to delete (outlier 1041 on 'a_d052_p' column)
107 a 1041 10.0 10385.0 0.1 10400 # Row to delete (outlier 1041 on 'price' column)
107 b 10400 10.0 10386.0 0.1 10400
107 b 10399 9.0 10387.0 0.2 10402
107 a 10399 9.0 10387.0 0.3 10404
我要删除仅在“价格”,“ b_d100_p”和“ a_d052_p”列上包含异常值的行。 为此,我选择使用基于标准偏差的条件。这是我尝试的代码。
row_with_potential_outliers = ['price', 'b_d100_p', 'a_d052_p']
df = df[abs((df[row_with_potential_outliers] - df[row_with_potential_outliers].mean()) / df[row_with_potential_outliers].std()) < 1.5] # The value '1.5' here is arbitrary, and does not matter too much
print(df)
side price b_d100_v b_d100_p a_d052_v a_d052_p
101 NaN 10400.0 NaN 10390.0 NaN 10399.0
102 NaN 10400.0 NaN 10391.0 NaN 10403.0
102 NaN 10400.0 NaN 10390.0 NaN 10400.0
104 NaN 10380.0 NaN 10390.0 NaN 10401.0
105 NaN NaN NaN 10390.5 NaN NaN # Row to delete (outlier 1041 on 'price' and 'a_d052_p' columns)
106 NaN 10400.0 NaN 10385.0 NaN NaN # Row to delete (outlier 1041 on 'a_d052_p' column)
107 NaN NaN NaN 10385.0 NaN 10400.0 # Row to delete (outlier 1041 on 'price' column)
107 NaN 10400.0 NaN 10386.0 NaN 10400.0
107 NaN 10399.0 NaN 10387.0 NaN 10402.0
107 NaN 10399.0 NaN 10387.0 NaN 10404.0
如何保留列“ side”,“ b_d100_v”和“ a_d052_v”的原始值?这将允许我然后应用'dropna()'来实现目标……也许还有更好的解决方案? 我使用具有数百列和数千行的数据框,因此出于性能原因,我想尽可能避免迭代。 预先感谢您的帮助。
答案 0 :(得分:2)
首先,要使用专有名称,请使用以下命令设置列表名称 列进行检查,就像 cols_to_check :
cols_to_check = ['price', 'b_d100_p', 'a_d052_p']
请注意,尚未找到具有异常值的行。 您仅指定哪些列来检查异常值。
然后定义一个函数来查找异常值 列,并具有指定的阈值:
def isOutlier(col, thr):
return ((col - col.mean()) / col.std()).abs() > thr
要删除带有异常值的行,请运行:
df = df[~df[cols_to_check].apply(isOutlier, thr=1.5).any(axis=1)]
结果是:
side price b_d100_v b_d100_p a_d052_v a_d052_p
101 a 10400 1.0 10390.0 11.0 10399
102 a 10400 1.0 10391.0 11.0 10403
102 a 10400 1.0 10390.0 11.0 10400
104 b 10380 0.3 10390.0 9.3 10401
107 b 10400 10.0 10386.0 0.1 10400
107 b 10399 9.0 10387.0 0.2 10402
107 a 10399 9.0 10387.0 0.3 10404
要完全理解该代码的工作方式,
要查看检查是否有任何元素是完整元素的完整结果 离群值,在其列中,运行:
df[cols_to_check].apply(isOutlier, thr=1.5)
您将 isOutlier 函数应用于 cols_to_check 列表中的每一列, 通过所选的阈值。结果是:
price b_d100_p a_d052_p
101 False False False
102 False False False
102 False False False
104 False False False
105 True False True
106 False False True
107 True False False
107 False False False
107 False False False
107 False False False
获取每一行的累积结果(是否为 any 元素 连续 True ),运行:
df[cols_to_check].apply(isOutlier, thr=1.5).any(axis=1)
结果是:
101 False
102 False
102 False
104 False
105 True
106 True
107 True
107 False
107 False
107 False
dtype: bool
因此,如果您运行df[~...]
,则会在上述情况下获得行
是 False ,并且仅将此结果保存回 df 中。
请注意,您要删除包含至少一个异常值的行, 不要将异常值更改为 NaN (因为这是代码的结果)。
答案 1 :(得分:1)
要使您的方法提供所需的输出,您只需要将异常值移除应用于数据框df
的指定列
df[row_with_potential_outliers] = df[row_with_potential_outliers][abs((df[row_with_potential_outliers] - df[row_with_potential_outliers].mean()) / df[row_with_potential_outliers].std()) < 1.5]
side price b_d100_v b_d100_p a_d052_v a_d052_p
101 a 10400.0 1.0 10390.0 11.0 10399.0
102 a 10400.0 1.0 10391.0 11.0 10403.0
102 a 10400.0 1.0 10390.0 11.0 10400.0
104 b 10380.0 0.3 10390.0 9.3 10401.0
105 a NaN 10.0 10390.5 0.1 NaN
106 a 10400.0 10.0 10385.0 0.1 NaN
107 a NaN 10.0 10385.0 0.1 10400.0
107 b 10400.0 10.0 10386.0 0.1 10400.0
107 b 10399.0 9.0 10387.0 0.2 10402.0
107 a 10399.0 9.0 10387.0 0.3 10404.0