我的Numpy数组包含10列和大约200万行.
现在,我需要分别分析每列,找到离群值;并从数组中删除整个对应的行.
因此,我将开始分析第0列;在第10,20,100行找到异常值;并删除这些行.
接下来,我将开始分析现在修剪后的数组中的第1列;并应用相同的过程.
当然,我可以想到执行此操作的常规手动过程(遍历每列,查找异常值,删除行,继续至另一列),但是我一直发现Numpy包含一些快速精妙的技巧来完成统计这些任务.
并且如果您可以详细说明该方法的运行时成本;更好.
我不限于NumPy库,如果SciPy有帮助的话,使用它就不会有问题.
谢谢!
解决方法:
两种非常简单的方法,第二种方法更加复杂:
arr = np.random.randn(2e6, 10)
def remove_outliers(arr, k):
mu, sigma = np.mean(arr, axis=0), np.std(arr, axis=0, ddof=1)
return arr[np.all(np.abs((arr - mu) / sigma) < k, axis=1)]
def remove_outliers_bis(arr, k):
mask = np.ones((arr.shape[0],), dtype=np.bool)
mu, sigma = np.mean(arr, axis=0), np.std(arr, axis=0, ddof=1)
for j in range(arr.shape[1]):
col = arr[:, j]
mask[mask] &= np.abs((col[mask] - mu[j]) / sigma[j]) < k
return arr[mask]
性能取决于您拥有多少离群值:
In [38]: %timeit remove_outliers(arr, 1)
1 loops, best of 3: 1.13 s per loop
In [39]: %timeit remove_outliers_bis(arr, 1)
1 loops, best of 3: 983 ms per loop
In [40]: %timeit remove_outliers(arr, 2)
1 loops, best of 3: 1.21 s per loop
In [41]: %timeit remove_outliers_bis(arr, 2)
1 loops, best of 3: 1.51 s per loop
而且当然:
In [42]: np.allclose(remove_outliers(arr, 1), remove_outliers_bis(arr, 1))
Out[42]: True
In [43]: np.allclose(remove_outliers(arr, 2), remove_outliers_bis(arr, 2))
Out[43]: True
我会说第二种方法的复杂性并不能证明其潜在的加速效果,而是YMMV …