【问题标题】:Replace multiple value of DataFrame column using loop (Outlier treatment)使用循环替换 DataFrame 列的多个值(异常值处理)
【发布时间】:2019-12-05 16:02:51
【问题描述】:

我正在尝试替换“LotFrontage”列的异常值 如果值小于最小值,则将我的 DataFrame 的第 5 个百分位 如果大于最大值,则上限为 95%。我想做这个 仅使用 for 循环。我试图写这个简单的函数,但这是 不工作。这几天我一直在为此苦苦挣扎,我 可以使用 numpy 解决这个问题,但只想使用 for 循环来解决这个问题。 任何帮助表示赞赏

def outlier(x):
    # taking 5,25,75 percentile of column
    q5= np.percentile(x,5)
    q25=np.percentile(x,25)
    q75=np.percentile(x,75)
    dt=np.percentile(x,95)
    #calculationg IQR range
    IQR=Q3-Q1
    #Calculating minimum threshold
    min=q25-(1.5*IQR)
    max=q75+(1.5*IQR)
    #Calculating maximum threshold
    for i in x:
        if x[i] > max:
            x[i].replace(x[i],dt)
        elif x[i] < min:
            x[i].replace(x[i],q5)
        else:
            x[i]
    print(q5,q25,q75,dt,min,max)

    return

将上述函数应用于DataFrame的一列

outlier(Sdata["LotFrontage"])

如果您需要任何其他信息,请告诉我

数据: 当我在我的专栏上应用此功能时出现以下错误:

ValueError:Series 的真值不明确。使用a.empty, a.bool()、a.item()、a.any() 或 a.all()。

【问题讨论】:

  • 您能否尝试将测试数据添加到您的示例中,并显示您如何准确调用函数outlier
  • 我使用 Sdata["LotFrontage"].apply(outlier) 调用函数异常值,如果有帮助请告诉我。测试数据在问题中可用。如果您仍然没有找到,请告诉我。
  • 好吧,所以我假设Sdata 是一个数据框,outlinerSeries 作为输入参数。我认为在您的示例中,如果您执行 for i in x 其中 x 是 Series 您迭代值而不是索引。所以i 取值:70、70、80 等。pandas.pydata.org/pandas-docs/stable/reference/api/… 如果您提供完整代码,调试它并说更多内容会更容易。
  • @lolnoob 你是对的。这是我唯一想要在函数中使用 For 循环替换列的异常值的代码。但是您已经正确理解了,并且在我的问题中可以看到完整的代码。似乎我的代码没有迭代,

标签: python pandas for-loop replace outliers


【解决方案1】:

而不是 numpy 或 for 循环,您可以使用 pandas 的简单赋值来执行此替换。在outlier 函数中作为x 您的pandas.Series,您可以将整个最终的for 循环替换为:

x[x < vmin] = q5
x[x > vmax] = dt

你就完成了。
请注意,在这里我将您的 min 重命名为 vmin 并将您的 max 重命名为 vmaxminmax 是 Python 内置函数,像 Python 内置函数一样命名变量可能会造成混淆。

但是,既然你问了一个for 循环,如果你真的想使用一个循环,它应该是这样的:

for i in range(len(x)):
    if x[i] > vmax:
        x[i] = dt
    elif x[i] < vmin:
        x[i] = q5

因为i 需要是索引。

最后,记得return x。您的调用应如下所示:

Sdata["LotFrontage"] = outlier(Sdata["LotFrontage"])

【讨论】:

  • @Valentio 我使用了更改后的代码,但仍然出现同样的错误。 def outlier(x): q5= np.percentile(x,5) q25=np.percentile(x,25) q75=np.percentile(x,75) dt=np.percentile(x,95) #calculationg IQR范围IQR=Q3-Q1 vmin=q25-(1.5*IQR) vmax=q75+(1.5*IQR) #计算范围内i的最大阈值(len(x)): if x[i] > vmax: x[i]= dt elif x[i]
  • 你对我申请的数据运行了这个函数吗?对我来说,它仍然给出了同样的错误。
  • 我无法从图像中获取数据,因此我没有在您的数据上进行尝试。我尝试使用一些随机数并成功了。尝试print(x) 并确保它是Series。错误提示并非如此。
【解决方案2】:

当您运行Sdata["LotFrontage"].apply(outlier) 时,它实际上会使用pd.Series Sdata["LotFrontage"] 中的每个值调用该函数。你想运行outlier(Sdata["LotFrontage"])

编辑: 您还需要将for i in x: 替换为for i,value in enumerate(x):

编辑:这是一个可能的解决方案:

def outlier(x):
    # taking 5,25,75 percentile of column
    q5= np.percentile(x,5)
    q25=np.percentile(x,25)
    q75=np.percentile(x,75)
    dt=np.percentile(x,95)
    #calculationg IQR range
    IQR=q75-q25
    #Calculating minimum threshold
    lower_bound=q25-(1.5*IQR)
    upper_bound=q75+(1.5*IQR)
    #Calculating maximum threshold
    print(q5,q25,q75,dt,min,max)
    return x.apply(lambda y: dt if y > upper_bound else y).apply(lambda y: q5 if y < lower_bound else y)

outlier(Sdata["LotFrontage"])

【讨论】:

  • 你能给我这个循环的解决方案吗?另外,我要求您在我提供的数据上应用该循环,因为循环解决方案在我的情况下不起作用。
猜你喜欢
  • 1970-01-01
  • 2022-01-13
  • 2021-09-24
  • 1970-01-01
  • 2023-03-15
  • 2014-11-11
  • 1970-01-01
  • 1970-01-01
  • 2021-09-28
相关资源
最近更新 更多