【问题标题】:Removing rows in NumPy efficiently有效地删除 NumPy 中的行
【发布时间】:2015-10-30 08:41:00
【问题描述】:

我有一个带有很多 ID 值的大型 numpy 数组(称为 X):

X:
id   rating
1    88
2    99
3    77
4    66
...

等等。我还有另一个 numpy 数组“坏 ID”——表示我想从 X 中删除的行。

B: [2, 3]

所以当我完成后,我想:

X:
id   rating
1    88
4    66

没有迭代的最干净的方法是什么?

【问题讨论】:

标签: python numpy


【解决方案1】:

这是我能想到的最快的方法:

import numpy

x = numpy.arange(1000000, dtype=numpy.int32).reshape((-1,2))
bad = numpy.arange(0, 1000000, 2000, dtype=numpy.int32)

print x.shape
print bad.shape

cleared = numpy.delete(x, numpy.where(numpy.in1d(x[:,0], bad)), 0)
print cleared.shape

打印出来:

(500000, 2)
(500,)
(499500, 2)

并且运行速度比 ufunc 快得多。它会使用一些额外的内存,但这是否适合您取决于您​​的数组有多大。

说明:

  • numpy.in1d 返回一个与x 大小相同的数组 如果元素在 bad 数组中,则包含 True,并且 False 否则。
  • numpy.whereTrue/False 数组转换为整数数组,其中包含数组为 True 的索引值。
  • 然后它将索引位置传递给numpy.delete,告诉它沿第一个轴 (0) 删除

【讨论】:

  • +1,我怀疑这是最好的解决方案(避免使用 ufunc 并且与我的相比非常快)。
  • 谢谢!这对我来说比其他 cmets (stackoverflow.com/questions/1962980/…) 中引用的解决方案要快得多
【解决方案2】:

从 OP 复制问题规范:

X = NP.array('1 88 2 99 3 77 4 66'.split(), dtype=int).reshape(4, 2)
bad_ids = [3,2]
bad_ideas = set(bad_ideas)    # see jterrance comment below this Answer

Vectorize 一个来自 Python 成员资格测试的插件——即,X in Y 语法

@NP.vectorize
def filter_bad_ids(id) :
    return id not in bad_ids


>>> X_clean = X[filter_bad_ids(X[:,0])]
>>> X_clean                                # result
   array([[ 1, 88],
          [ 4, 66]])

【讨论】:

  • in 不是需要 O(N) 时间来获取列表吗?你可能应该让bad_ids = set([3,2])
  • @jterrance--谢谢(根据您的评论编辑了我的答案)。
  • 感谢您的帮助,但其他解决方案在我的数据集上的执行速度明显更快。
【解决方案3】:

如果您想完全删除错误 ID 的信息,请尝试以下操作:

x = x[numpy.in1d(x[:,0], bad, invert=True)]

此解决方案使用的内存非常少,应该非常快。 (bad 被转换为一个 numpy 数组,所以不应该是这样的集合,请参阅http://docs.scipy.org/doc/numpy/reference/generated/numpy.in1d.html 中的注释)
如果 bad 非常小,它可能会更快一点:

from functools import reduce
x = x[~reduce(numpy.logical_or, (x[:,0] == b for b in bad))]

注意:第一行仅在 Python3 中是必需的。
由于使用了生成器,这也使用了很少的内存。

【讨论】:

    猜你喜欢
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 2014-01-02
    • 2023-01-26
    • 2023-02-07
    • 1970-01-01
    相关资源
    最近更新 更多