Python 避免查询局部异常值的ItError

Python 避免查询局部异常值的ItError,python,pandas,vectorization,kdtree,Python,Pandas,Vectorization,Kdtree,对于包含坐标列(例如“x”、“y”)的数据帧,我想检查相关值“val”是否偏离局部(到坐标的距离

对于包含坐标列(例如“x”、“y”)的数据帧,我想检查相关值“val”是否偏离局部(到坐标的距离<半径)邻域中“val”的平均值。我发现了以下经常使用的方法(例如or),构建KDTree并查询每一行的局部平均值。但是,我想知道是否有更好的解决方案可以防止数据帧迭代导致更快的执行

import pandas as pd
import numpy as np
from sklearn.neighbors import KDTree

xy = np.mgrid[0:10,0:10]
df = pd.DataFrame({'x':xy[0].ravel(), 'y':xy[1].ravel(), 'val':np.random.rand(100)})

tree = KDTree(df[['x', 'y']].values, metric='euclidean')

radius = 5
for i, row in df.iterrows():
    coords = row[['x', 'y']].values.reshape(1, -1)
    idx = tree.query_radius(coords, r=radius)[0]
    df.loc[i, 'outlier'] = np.abs(row['val'] - df.iloc[idx]['val'].mean()) > df.iloc[idx]['val'].std()
df = df[df["outlier"] == False] #select df without outlier

我还没有弄明白,要避免所有的循环可能还有很多方法,但一个简单的解决方案是将所需的值放入数组中,然后对这些数组执行向量化操作。我做了一些测试,平均减少了大约40%的执行时间

coords = df[['x','y']].apply(lambda row: row.values.reshape(1,-1),axis=1)
df.coords = coords
idx = coords.apply(lambda x: tree.query_radius(x,r=radius)[0])
means = idx.apply(lambda x: df.loc[x,'val'].mean())
df.means = means
stds = idx.apply(lambda x: df.loc[x,'val'].std())
df.stds = stds
df['outlier']=np.abs(df['val']-df.means)>df.stds

好的,很酷,这已经是一个进步了!