【问题标题】:Flipping zeroes and ones in one-dimensional NumPy array翻转一维 NumPy 数组中的零和一
【发布时间】:2014-11-12 15:25:25
【问题描述】:

我有一个一维 NumPy 数组,它由 0 和 1 组成,如下所示:

array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])

我想要一种快速的方法来“翻转”值,使零变成一,一变成零,从而产生一个像这样的 NumPy 数组:

array([1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

是否有一个简单的单行代码?我查看了fliplr() 函数,但这似乎需要二维或更大维度的 NumPy 数组。我敢肯定有一个相当简单的答案,但任何帮助将不胜感激。

【问题讨论】:

  • 注意: Python 有布尔值,NumPy 也有。使用它们,而不是 0/1'0'/'1'

标签: python arrays numpy


【解决方案1】:

你的 Q 中一定有我不明白的地方......

不管怎样

In [2]: from numpy import array

In [3]: a = array((1,0,0,1,1,0,0))

In [4]: b = 1-a

In [5]: print a ; print b
[1 0 0 1 1 0 0]
[0 1 1 0 0 1 1]

In [6]: 

【讨论】:

  • 这应该是公认的答案。这是最简单的解决方案
  • 确实很简单,+1。唯一的潜在问题是就地进行并不容易。正因为如此,我更喜欢使用按位异或,a = a ^ 1,它可以让你做a ^= 1
  • @Jaime 你应该提供这个作为答案a ^= 1简洁和pythonic。谢谢!
  • 为什么选择这个而不是 numpy.logical_not()~?特别是因为 OP 显然使用的是布尔值。
【解决方案2】:

表明您可能应该使用布尔数据类型

a = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=np.bool)
# or
b = ~a
b = np.logical_not(a)

【讨论】:

  • 我喜欢解决问题而不是问题的答案。
【解决方案3】:

另一个多余的选择:

numpy.logical_not(a).astype(int)

【讨论】:

  • 赞成。我不确定引擎盖下的操作,但我想当它使用逻辑操作时它会更快(翻转位可能比算术更快)。我在其他答案中看到过,但我喜欢它只投射一次,并在此过程中恢复类型。
  • 如果您就地执行 (out=a),在这种情况下它将保留原始 dtype。
【解决方案4】:

在数学上,首先想到的是(value + 1) % 2

>>> (a+1)%2
array([1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)

【讨论】:

  • 喜欢这个。快速、简洁、合乎逻辑。谢谢你。
  • 快速、简洁、合乎逻辑?模数太慢了,我认为没有比@gboffi 的答案更合乎逻辑和更快的了;)
  • @tamasgal 你对这个答案是正确的,但不是 gboffi 的答案。使用实际的布尔值要好得多。
  • @AMC 好吧,转换为 bool 并进行位移比减法更快,但如果您再次需要整数,性能会更差。所以这取决于你想要什么类型。我想保留数据类型(int),bgoffi 有最好的答案,“逻辑和快速”。如果一个布尔值作为结果是可以接受的,YXD 的答案是最快的。我还用 1e6 随机 0/1s 检查了 REPL,它是 2.5ms(减法)、0.9ms(bool-bitshift)和 3.9ms(bool-bitshift-back_to_int)。但是感谢您提出这个问题,持怀疑态度总是好的! :)
  • @tamasgal 我不是在谈论性能,我认为这不是什么大问题。不过我有点好奇:你能对np.logical_not(arr, out=arr) 进行基准测试吗?
【解决方案5】:
answer = numpy.ones_like(a) - a

【讨论】:

  • (其实@gboffi 的回答更好)
【解决方案6】:

我也找到了办法:

In [1]: from numpy import array

In [2]: a = array([1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

In [3]: b = (~a.astype(bool)).astype(int)


In [4]: print(a); print(b)
[1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 1 1 1 1 1 1 1 1 1 1]

不过,我认为@gboffi 的回答是最好的。我会投赞成票,但我还没有足够的声誉:(

【讨论】:

  • 欢迎来到 Stack Overflow!如果一个问题已经得到解答——尤其是 3 年前的问题(!)——请不要添加你知道的解决方案不如所选的解决方案。祝你好运!
猜你喜欢
  • 1970-01-01
  • 2011-08-22
  • 2017-12-24
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多