【问题标题】:how to exclude `x` from `range(n)` using numpy如何使用numpy从`range(n)`中排除`x`
【发布时间】:2019-12-17 14:33:38
【问题描述】:

我想创建一个从 1 到 n 的数字数组,没有数字 x

有没有“更漂亮”的方式来代替[i for i in range(n) if i != x]? 谢谢!

【问题讨论】:

  • 为什么[i for i in range(n) if i != x]不漂亮?
  • @AK47 好吧,我正在寻找一种内置的东西,可以让它更短更直接
  • @apet,OP 想要内置的东西!
  • 我重新打开了这个问题,因为标记的骗子只有纯 python 的解决方案,并且 OP 明确询问了numpy

标签: python list numpy range


【解决方案1】:

np.r_ 使用高级索引。

np.arange(n)[np.r_[0:x, x+1:n]]

def myrange(n, exclude):
    return np.arange(n)[np.r_[0:exclude, exclude+1:n]]

>>> myrange(10, exclude=3)
array([0, 1, 2, 4, 5, 6, 7, 8, 9])

Timings

%timeit myrange(10000000, 7008)
1 loop, best of 3: 79.1 ms per loop

%timeit other(10000000, 7008)
1 loop, best of 3: 952 ms per loop

在哪里

def myrange(n, exclude):
    return np.arange(n)[np.r_[0:exclude, exclude+1:n]]

def other(n, exclude):
    return [i for i in range(n) if i != x]

【讨论】:

  • 如果我为它创建一个函数,我不应该只使用[i for i in range(n) if i != x],因为它更容易阅读吗?在这种情况下,高级索引有什么优势吗?
  • @Tomergt45 当然更容易阅读,但速度较慢。函数名称myrange 和一些文档字符串应该可以使它变得可读,并且您仍然可以从快速的速度中受益。我添加了一些时间来说明。另一个细节是列表推导产生一个python列表,而np.arange +np.r_直接给出一个numpy数组
【解决方案2】:

您可以连接两个范围:

np.concatenate((np.arange(x), np.arange(x + 1, n)))

您也可以删除一个项目:

np.delete(np.arange(n), x)

你可以屏蔽:

mask = np.ones(n, dtype=bool)
mask[x] = False
np.arange(n)[mask]

您甚至可以使用掩码数组,具体取决于您的应用程序:

a = np.ma.array(np.arange(n), mask=np.zeross(n, dtypebool))
a.mask[x] = True=

【讨论】:

    【解决方案3】:

    我建议使用itertools.chain

    for a in itertools.chain(range(x), range(x+1, n)):
        print(a)
    

    list(itertools.chain(range(x), range(x+1, n)))
    

    我不知道为什么,但是[itertools.chain(range(x), range(x+1, n))] 不起作用。

    编辑:感谢@rafaelc 如何使它在方括号上工作。

    [*itertools.chain(range(x), range(x+1, n))]
    

    【讨论】:

    • [*itertools.chain(range(x), range(x+1, n))] 可以。你必须打开它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多