我有一个numpy数组,其中包含1和0的随机分布。我想用0替换所有1,用1替换所有零。
arr[arr == 0] = 2
arr[arr== 1] = 0
arr[arr== 2] = 1
我目前必须使用一个临时值(在这种情况下为2),以避免所有0变为1,然后使整个数组充满0。 有没有更优雅/有效的方法来做到这一点?
答案 0 :(得分:3)
您可以在覆盖任何值之前计算并存储布尔索引器:
ones = a == 1
zeros = a == 0
a[ones] = 0
a[zeros] = 1
如果您使用0
和1
以外的其他值,则该解决方案也适用。
如果不需要就地解决方案,则可以使用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^1
和1 - 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