【问题标题】:Delete an item in a list, if outside the IQR [duplicate]如果在 IQR 之外,则删除列表中的项目 [重复]
【发布时间】:2014-12-11 21:23:51
【问题描述】:

如果列表中的某个项目超出中位数的四分位范围,我会尝试从列表中删除它。

这里是列表:

l = [69, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 87, 89]

IQR、中位数和中位数上下均与import numpy as np一起使用

iqr = np.subtract(*np.percentile(l, [75, 25]))
median = np.percentile(l, 50)
minus = median - iqr
plus = median + iqr

负数为 69,正数为 71(使用中位数上下的 IQR)

但是,当遍历列表并尝试删除高于/低于 iqr 的项目 (87、89) 时。它们不会从列表中删除。

for i in l:
    if i < minus:
        del i
    if i > plus:
        del i

当我打印列表时,它仍然显示 87、89。

【问题讨论】:

  • 您的循环没有对列表进行任何更改。虽然i 从列表中弹出,但它不受列表的限制。所以del i 根本不碰l

标签: python numpy


【解决方案1】:
for  ele in l[:]:
    if ele < minus or ele > plus:
        l.remove(ele)

您必须复制 l l[:] 并使用 l.remove 改变实际列表本身

【讨论】:

  • 我想你的意思是l.pop(i)
  • IndexError: pop index out of range. 这是l.pop(i)
  • @JonathanDavies,使用 remove 但删除元素时必须复制列表,不能迭代并从同一对象中删除元素
  • @PadraicCunningham Grand,这非常有效。感谢您的帮助!
  • 别担心,不客气
【解决方案2】:

del 不是您要查找的运算符。它用于删除对对象的引用,因此在垃圾回收中很有用。

您可能正在寻找这个:

import numpy as np
l = [69, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 87, 89]
iqr = np.subtract(*np.percentile(l, [75, 25]))
median = np.percentile(l, 50)
minus = median - iqr
plus = median + iqr

arr = np.array(l)
arr[ (minus < arr) & (arr < plus)]

【讨论】:

  • del 不仅仅用于垃圾收集,即从dict 中删除条目。它也可用于从列表中删除条目。例如x =["a", "b", "c", "d"],那么del x[1] 给出["a", "c", "d"]
  • @jme,有人指出这一点只是时间问题 :-) 我会在两种情况下都使用列表和字典的显式方法pop,因为它们是为它们设计的这个目的。
  • 我在不同的场景中使用它们。如果我真的想摆脱该条目,我使用del。如果我想删除条目但对值做一些事情,我使用pop 方法。出于某种原因,看到pop 没有分配返回值让我感到不舒服;在这些情况下,del 在我看来更惯用。另外del 提供了一种简洁的删除切片的方法,例如del x[2:4],据我所知,这不能使用列表或字典容器的方法来完成。
  • @jme,很好的用例,没想到!
【解决方案3】:

只需将其转换为 numpy 数组,然后从那里进行数学运算:

l = np.array(l)
l[(l >= 69) & (l <= 71)]

就是这样。

【讨论】:

  • 我认为您的布尔逻辑混淆了:现在您正在选择 IQR 之外的元素。
  • 确定!谢谢@OliverW。
  • 没问题。可能只是因为我们想到了相同的解决方案才注意到它。
猜你喜欢
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
相关资源
最近更新 更多