首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >熊猫离群点有无计算

熊猫离群点有无计算
EN

Stack Overflow用户
提问于 2022-10-28 14:19:09
回答 2查看 62关注 0票数 0

我正在考虑在一个拥有300多个特性的数据集中对离群点做出决策。我想在不匆忙删除数据的情况下对框架进行分析。我有一个框架:

代码语言:javascript
复制
 |    |   A |   B |    C |   D |   E |
 |---:|----:|----:|-----:|----:|----:|
 |  0 | 100 |  99 | 1000 | 300 | 250 |
 |  1 | 665 |   6 |    9 |   1 |   9 |
 |  2 |   7 | 665 |    4 |   9 |   1 |
 |  3 |   1 |   3 |    4 |   3 |   6 |
 |  4 |   1 |   9 |    1 | 665 |   5 |
 |  5 |   3 |   4 |    6 |   1 |   9 |
 |  6 |   5 |   9 |    1 |   3 |   2 |
 |  7 |   1 | 665 |    3 |   2 |   3 |
 |  8 |   2 | 665 |    9 |   1 |   0 |
 |  9 |   5 |   0 |    7 |   6 |   5 |
 | 10 |   0 |   3 |    3 |   7 |   3 |
 | 11 |   6 |   3 |    0 |   3 |   6 |
 | 12 |   6 |   6 |    5 |   1 |   5 |

我编写了一些内省代码,以便保存在另一个名为_outliers的框架中:

代码语言:javascript
复制
Q1 = df.quantile(0.25)
Q3 = df.quantile(0.75)
IQR = (Q3 - Q1)
min_ = (Q1 - (1.5 * IQR))
max_ = (Q3 + (1.5 * IQR))
# Counts outliers in columns
_outliers = ((df.le (min_)) | (df.ge (max_))).sum().to_frame(name="outliers")
# Gives percentage of data that outliers represent in the column
_outliers["percent"] = (_outliers['outliers'] / _outliers['outliers'].sum()) * 100
# Shows max value in the column
_outliers["max_val"] = df[_outliers.index].max()
# Shows min value in the column
_outliers["min_val"] = df[_outliers.index].min()
# Shows median value in the column
_outliers["median"] = df[_outliers.index].median()
# Shows mean value in the column
_outliers["mean"] = df[_outliers.index].mean()

这会产生:

代码语言:javascript
复制
|    |   outliers |   percent |   max_val |   min_val |   median |     mean |
|:---|-----------:|----------:|----------:|----------:|---------:|---------:|
| A  |          2 |   22.2222 |       665 |         0 |        5 |  61.6923 |
| B  |          3 |   33.3333 |       665 |         0 |        6 | 164.385  |
| C  |          1 |   11.1111 |      1000 |         0 |        4 |  80.9231 |
| D  |          2 |   22.2222 |       665 |         1 |        3 |  77.0769 |
| E  |          1 |   11.1111 |       250 |         0 |        5 |  23.3846 |

我想通过计算没有异常值的平均值和中位数来计算离群值对列的影响。我不想删除它们来做这个计算。我认为最好的方法是在离群点过滤器中添加"~“,但我在代码中迷失了方向.这将使许多人受益,因为搜索删除异常值会产生很多结果。除了他们从一开始就潜入数据的原因之外,我只是不认为在不考虑潜在影响的情况下做出删除决定。可以随意添加其他考虑因素(偏度、西格玛、n等)。

和往常一样,我很感激这个社区!

编辑:我添加了方差和它的平方根标准差带和不带异常值。在某些字段中,您可能希望保留异常值并直接进入ML。至少,通过预先检查您的数据,您将知道它们对您的结果有多大的贡献。在离群值列中与most ()一起使用,您可以快速查看哪些特性包含的最多。您可以将此作为筛选功能的基础,方法是设置方差或平均值的阈值。感谢撰稿人,我现在有了一个强大的分析工具。希望它能对其他人有用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-28 18:05:09

充分利用DataFrameDataFrame方法。

串联发生器

只需通过创建一个使用Series的方法并返回标量并将其应用到您的DataFrame中,就可以定义您希望健壮的方法应用的方式。

对于IRQ平均值,下面是一个简单的片段:

代码语言:javascript
复制
def irq_agg(x, factor=1.5, aggregate=pd.Series.mean):
    q1, q3 = x.quantile(0.25), x.quantile(0.75) 
    return aggregate(x[(q1 - factor*(q3 - q1) < x) & (x < q3 + factor*(q3 - q1))])

data.apply(irq_agg)

# A     3.363636
# B    14.200000
# C     4.333333
# D     3.363636
# E     4.500000
# dtype: float64

也可以根据百分位数(两边版本)进行过滤:

代码语言:javascript
复制
def quantile_agg(x, alpha=0.05, aggregate=pd.Series.mean):
    return aggregate(x[(x.quantile(alpha/2) < x) & (x < x.quantile(1 - alpha/2))])

data.apply(quantile_agg, alpha=0.01)

# A    12.454545
# B    15.777778
# C     4.727273
# D    41.625000
# E     4.909091
# dtype: float64

帧发生器

更好的是,创建一个返回Series的函数,apply将创建一个DataFrame。然后我们可以一次计算出一堆不同的方法和中间值来比较它们。我们还可以重用上面定义的Series生成器方法:

代码语言:javascript
复制
def analyze(x, alpha=0.05, factor=1.5):
    return pd.Series({
        "p_mean": quantile_agg(x, alpha=alpha),
        "p_median": quantile_agg(x, alpha=alpha, aggregate=pd.Series.median),
        "irq_mean": irq_agg(x, factor=factor),
        "irq_median": irq_agg(x, factor=factor, aggregate=pd.Series.median),
        "standard": x[((x - x.mean())/x.std()).abs() < 1].mean(),
        "mean": x.mean(),
        "median": x.median(),
    })

data.apply(analyze).T

#       p_mean  p_median   irq_mean  irq_median   standard        mean  median
# A  12.454545       5.0   3.363636         3.0  11.416667   61.692308     5.0
# B  15.777778       6.0  14.200000         5.0  14.200000  164.384615     6.0
# C   4.727273       4.0   4.333333         4.0   4.333333   80.923077     4.0
# D  41.625000       4.5   3.363636         3.0   3.363636   77.076923     3.0
# E   4.909091       5.0   4.500000         5.0   4.500000   23.384615     5.0

现在,您可以通过几种方法筛选出离群值,在其上计算相关的聚合,例如平均值或中值。

票数 1
EN

Stack Overflow用户

发布于 2022-10-29 01:32:32

对于这是否是筛选出异常值的适当方法,没有任何评论。下面的代码应该按照您的要求执行:

代码语言:javascript
复制
q1, q3 = df.quantile([0.25, 0.75]).to_numpy()
delta = (q3 - q1) * 1.5
min_val, max_val = q1 - delta, q3 + delta
outliers = (df < min_val) | (max_val < df)

result = pd.concat(
    [
        pd.DataFrame(
            {
                "outliers": outliers.sum(),
                "percent": outliers.sum() / outliers.sum().sum() * 100,
                "max_val": max_val,
                "min_val": min_val,
            }
        ),
        df.agg(["median", "mean"]).T,
        df.mask(outliers, np.nan).agg(["median", "mean"]).T.add_suffix("_no_outliers"),
    ],
    axis=1,
)

结果:

代码语言:javascript
复制
   outliers    percent  max_val  min_val  median        mean  median_no_outliers  mean_no_outliers
A         2  15.384615     13.5     -6.5     5.0   61.692308                 3.0          3.363636
B         3  23.076923    243.0   -141.0     6.0  164.384615                 5.0         14.200000
C         1   7.692308     13.0     -3.0     4.0   80.923077                 4.0          4.333333
D         2  15.384615     16.0     -8.0     3.0   77.076923                 3.0          3.363636
E         1   7.692308     10.5     -1.5     5.0   23.384615                 5.0          4.500000
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74236711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档