【问题标题】:How to remove outliers from XY scatter plot如何从 XY 散点图中删除异常值
【发布时间】:2021-12-20 01:27:17
【问题描述】:

我正在处理一个具有 X 和 Y 值的项目,并且我尝试探索必须不存在数据的区域。从图中可以看出,大部分数据聚集在红线的两侧,也有一些数据在红线内。我只想删除那些异常值但无法实现。我尝试使用反向 KNN 算法或距离计算,但它们在我的数据中不起作用或者我做不到。有没有可能的解决方案?

我的散点图python代码如下。

import pyodbc
import matplotlib.pyplot as plt
from astroML.plotting import scatter_contour
import numpy as np
import pandas as pd

conn = pyodbc.connect('Driver={SQL Server};'
                      'Server=test;'
                      'Database=test;'
                      'Trusted_Connection=yes;')

sqlquery= "SELECT test FROM test"

SQL_Query = pd.read_sql_query (sqlquery, conn)


df = pd.DataFrame(SQL_Query, columns=['Data1', 'Data2'])

    
x = df['Data1']
y = df['Data2']
fig,ax = plt.subplots(1,1,figsize=(15,15))
scatter_contour(x,y, threshold=20, log_counts=True, ax=ax,
            histogram2d_args=dict(bins=45),
            plot_args=dict(marker='.', linestyle='none', color='black',
                          markersize=1),
            contour_args=dict(cmap='summer',),
           filled_contour=False)

【问题讨论】:

    标签: python matplotlib cluster-computing outliers


    【解决方案1】:

    最简单的方法是手动选择并删除您想要删除的值。更复杂的版本是计算核密度估计并过滤低于某个阈值的值。

    from scipy import stats
    
    ....
    
    xmin = x.min()
    
    xmax = x.max()
    
    ymin = y.min()
    
    ymax = y.max()
    
    #Perform a kernel density estimate on the data:
    
    X, Y = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]
    
    positions = np.vstack([X.ravel(), Y.ravel()])
    
    values = np.vstack([x, y])
    
    kernel = stats.gaussian_kde(values)
    
    Z = np.reshape(kernel(positions).T, X.shape)
    

    这将为您创建一个 2d 100x100 近似数据。如果您想要更详细的内核密度估计,您可以将此 100 值更改为更高的值。如果您将 x 数据缩放到 0 到 100 之间,那么低于您选择的阈值的 Z 值就是您要删除的点。

    df['x_to_scale'] = (100*(x - np.min(x))/np.ptp(x)).astype(int) 
    df['y_to_scale'] = (100*(y - np.min(y))/np.ptp(y)).astype(int) 
    
    to_delete = zip(*np.where((Z<your_threshold) == True))
    
    df.drop(df.apply(lambda x: (x['x_to_scale'], x['y_to_scale']), axis=1)
              .isin(to_delete)
              .loc[lambda x: x == True]
              .index)
    

    这将删除低于某个密度阈值的所有值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      相关资源
      最近更新 更多