numpy交换数组中的多个元素

时间:2018-11-19 21:34:35

标签: python arrays numpy

我有一个numpy数组,其中包含1和0的随机分布。我想用0替换所有1,用1替换所有零。

arr[arr == 0] = 2
arr[arr== 1] = 0
arr[arr== 2] = 1

我目前必须使用一个临时值(在这种情况下为2),以避免所有0变为1,然后使整个数组充满0。 有没有更优雅/有效的方法来做到这一点?

5 个答案:

答案 0 :(得分:3)

您可以在覆盖任何值之前计算并存储布尔索引器:

ones = a == 1
zeros = a == 0

a[ones] = 0
a[zeros] = 1

如果您使用01以外的其他值,则该解决方案也适用。


如果不需要就地解决方案,则可以使用np.where

a = np.where(ones, 0, np.where(zeros, 1, a))

答案 1 :(得分:3)

这是非常适合您的问题的解决方案,但也应该非常快。给定数组:

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

您可以从所有值中减去1,然后乘以负1:

>>> (a-1)*-1
array([[0, 1, 1, 0],
       [0, 0, 0, 1]])

答案 2 :(得分:3)

对于您的特定值,使用1按位异或。

In [19]: a=np.random.randint(2, size=10)

In [18]: a
Out[18]: array([1, 1, 1, 1, 1, 1, 0, 0, 1, 1])

In [19]: a^1
Out[19]: array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0])

更通用的int类型解决方案。

In [62]: convert=np.array([1,0])

In [63]: convert[a]
Out[63]: array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0])

更改'convert'数组的内容意味着可以映射一系列值。结果使用数组'a'的内容作为数组'convert'的索引。

答案 3 :(得分:2)

给出

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

您可以使用numpy.where

>>> np.where(a == 0, 1, 0) # read as (if, then, else)
array([[0, 1, 1, 0],
       [0, 0, 0, 1]])

...或否定a并进行一些类型转换。

>>> (~a.astype(bool)).astype(int)
array([[0, 1, 1, 0],
       [0, 0, 0, 1]])

(IPython)时间:没有太大差异。

>>> a = np.eye(1000, dtype=int)
>>> %timeit np.where(a == 0, 1, 0)
1.56 ms ± 2.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit (~a.astype(bool)).astype(int)
1.74 ms ± 87.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

其他人的答案的时间:

>>> %timeit a^1 # Tls Chris
920 µs ± 31.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit np.array([1, 0])[a] # Tls Chris
1.4 ms ± 102 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit (a - 1)*-1 # sacul
1.57 ms ± 13.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit 1 - a # user3483203
905 µs ± 2.16 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

我的看法:a^11 - a干净,优雅且快速。使用np.where可以处理您可能要交换的任何值。

答案 4 :(得分:1)

如果有效的解决方案比优雅的解决方案更重要,则可以编写一个非常简单的Numba解决方案。

示例

import numba as nb
import numpy as np

@nb.njit()
def nb_where(arr):
  for i in range(arr.shape[0]):
    for j in range(arr.shape[1]):
      if arr[i,j]==1:
        arr[i,j] = 0
      else:
        arr[i,j] = 1
  return arr

时间

a = np.eye(1000, dtype=int)
np.where(a == 0, 1, 0) #timgeb    -> 2.06ms 
a^1                    #Tls Chris -> 1.31ms 
nb_where(a)                       -> 152 µs