在大型pandas DataFrame中,按组快速移除异常值的方法

7 浏览
0 Comments

在大型pandas DataFrame中,按组快速移除异常值的方法

我有一个相对较大的DataFrame对象(大约一百万行,数百列),我想按组对每列的异常值进行截断。通过“按组截断每列的异常值”,我是指 - 在组中计算每列的5%和95%分位数,并截断超出此分位数范围的值。\n这是我目前使用的设置:\n

def winsorize_series(s):
    q = s.quantile([0.05, 0.95])
    if isinstance(q, pd.Series) and len(q) == 2:
        s[s < q.iloc[0]] = q.iloc[0]
        s[s > q.iloc[1]] = q.iloc[1]
    return s
def winsorize_df(df):
    return df.apply(winsorize_series, axis=0)

\n然后,对于我的名为features且以DATE为索引的DataFrame,我可以这样做:\n

grouped = features.groupby(level='DATE')
result = grouped.apply(winsorize_df)

\n这个方法有效,但是非常慢,可能是由于嵌套的apply调用:一个用于每个组,然后一个用于每个组中的每列。我尝试通过一次计算所有列的分位数来消除第二个apply,但在尝试为每列设置不同的阈值时遇到了困难。有没有更快的方法来完成这个过程?

0
0 Comments

快速删除大型pandas DataFrame中各组的异常值的方法

异常值是指在数据集中与其他观测值明显不同的观测值。在处理大型pandas DataFrame时,删除异常值是数据清洗的重要步骤之一。然而,对于每个组逐一处理异常值可能会非常耗时。因此,我们需要一种更快速的方法来处理大型DataFrame中的异常值。

下面给出了问题的解决方法:

1. 导入所需的库:

from scipy.stats import mstats

2. 定义一个函数,该函数使用mstats库中的winsorize函数来删除异常值。该函数将每个组作为参数,并返回处理后的组。

def winsorize_series(group):
    return mstats.winsorize(group, limits=[lower_lim,upper_lim])

3. 使用groupby方法将数据按照日期(level='DATE')分组。

grouped = features.groupby(level='DATE')

4. 使用transform方法将winsorize_series函数应用于每个组,并将结果保存到一个新的DataFrame中。

result = grouped.transform(winsorize_series)

通过使用transform方法,我们可以避免遍历每个组并逐一处理异常值。相反,transform方法可以对每个组进行一次操作,并将结果应用于原始DataFrame中的每个组。

这种方法的优点是能够更快速地处理大型pandas DataFrame中的异常值,从而提高数据清洗的效率。

0
0 Comments

在处理大型pandas DataFrame时,我们经常需要处理异常值。异常值可能会对我们的数据分析和建模产生不良影响,因此需要将其移除或替换掉。然而,在大型数据集中,处理异常值可能会变得非常耗时。

这里提供了一种快速移除DataFrame中异常值的方法,而不使用scipy.stats.mstats。具体方法如下:

def clip_series(s, lower, upper):
    clipped = s.clip(lower=s.quantile(lower), upper=s.quantile(upper), axis=1)
    return clipped
# 管理需要进行winsorize的特征列表
feature_list = list(features.columns)
for f in feature_list:
    features[f] = clip_series(features[f], 0.05, 0.95)

这段代码中定义了一个`clip_series`函数,该函数用于对传入的Series对象进行winsorize操作。winsorize操作是一种将数据中的极端值替换为接近边界值的方法。在`clip_series`函数中,我们使用了`quantile`方法来计算边界值,并使用`clip`方法将数据中小于边界值的值替换为边界值的下限,大于边界值的值替换为边界值的上限。

接下来,我们将需要进行winsorize的特征逐个传入`clip_series`函数,并将得到的处理后的Series对象重新赋值给原始DataFrame中的对应特征列,以实现对异常值的移除。

通过这种方法,我们能够更快速地处理大型pandas DataFrame中的异常值,从而提高数据处理的效率。

0
0 Comments

快速删除大型pandas DataFrame中每个组的异常值的方法

问题的原因:

在某个数据集中,需要对每个组的数据进行异常值的删除操作。目前已经使用了pandas中的clip()和quantile()函数来实现,但是这种方法无法正确处理缺失值,因为它会包含缺失值并且会影响非缺失数据的百分位数。

解决方法:

可以考虑使用scipy.stats.mstats中的winsorize函数来替代已有的winsorize_series函数。winsorize函数返回的结果与winsorize_series函数稍有不同,但是在某些情况下,使用winsorize函数可能会比winsorize_series函数快1.5倍。具体代码如下:

import numpy as np
import pandas as pd
from scipy.stats import mstats
def using_mstats_df(df):
    return df.apply(using_mstats, axis=0)
def using_mstats(s):
    return mstats.winsorize(s, limits=[0.05, 0.05])
N, M, P = 10**5, 10, 10**2
dates = pd.date_range('2001-01-01', periods=N//P, freq='D').repeat(P)
df = pd.DataFrame(np.random.random((N, M)), index=dates)
df.index.names = ['DATE']
grouped = df.groupby(level='DATE')
%timeit result = grouped.apply(winsorize_df)
%timeit mstats_result = grouped.apply(using_mstats_df)

其中,using_mstats_df函数会将每个组的数据应用到using_mstats函数中进行winsorize操作。通过使用grouped.apply函数,可以在整个DataFrame上进行批量操作,而不需要逐列操作,从而提高运行速度。

通过使用scipy.stats.mstats中的winsorize函数,可以快速删除大型pandas DataFrame中每个组的异常值。与已有的winsorize_series函数相比,使用winsorize函数可能会更快。通过使用grouped.apply函数,可以在整个DataFrame上进行批量操作,从而提高运行速度。需要注意的是,winsorize函数返回的结果与winsorize_series函数稍有不同。

0