假设我有一个 numpy 数组,我想将所有 1 交换为 0,将所有 0 交换为 1(该数组将具有其他值,并且 0 和 1 没有什么特别的)。当然,我可以循环遍历数组并逐一更改值。
有什么有效的方法可以推荐吗?
np.where()
方法有此操作的选项吗?
np.where
的一种方法,当给定值是 XOR
或 0
时,按位取 1
:
np.where((a==0)|(a==1), a^1, a)
例如:
a = np.array([[0,1,2,1], [1,2,0,3]])
print(a)
array([[0, 1, 2, 1],
[1, 2, 0, 3]])
np.where((a==0)|(a==1), a^1, a)
array([[1, 0, 2, 0],
[0, 2, 1, 3]])
对于 np.where,这是一个不太聪明的选项,只需将其用于索引:
where_0 = np.where(arr == 0)
where_1 = np.where(arr == 1)
arr[where_0] = 1
arr[where_1] = 0
如果您对其他值了解更多(例如它们都是小数字),可能会有更多选择,但这是最简单的。
a^(a&1==a)
例如
a = np.arange(-3, 4)
a^(a&1==a)
# array([-3, -2, -1, 1, 0, 2, 3])
一种非常简单的方法,不需要使用任何特殊方法,例如
np.where()
,就是获取 numpy
数组中变量条件的索引,并相应地分配所需的值(在您的情况下 0
(对于 1s
)和 1
(对于 0s
)到数组中各自的位置项。这也适用于 0s
和 1s
以外的值。此外,您不需要任何临时变量来交换值。
import numpy as np
arr = np.array([1, 0, 2, 3, 6, 1, 0])
indices_one = arr == 1
indices_zero = arr == 0
arr[indices_one] = 0 # replacing 1s with 0s
arr[indices_zero] = 1 # replacing 0s with 1s
Output: array([0, 1, 2, 3, 6, 0, 1])
iverted = ~arr + 2
应该做这项工作
最棘手的部分是
the array will have other values
。如果只有 0 和 1(没有其他值),arr = ~arr + 2
是最快的方法。如果需要考虑 the array will have other values
,请使用 arr^(arr&1==arr)
。这是基准。
%%timeit
np.random.seed(0)
arr = np.random.randint(0,2,100)
arr = ~arr + 2
38.8 µs ± 12 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
np.random.seed(0)
arr = np.random.randint(0,2,100)
where_1 = arr == 1
where_0 = arr == 0
arr[where_1] = 0 # replacing 1s with 0s
arr[where_0] = 1 # replacing 0s with 1s
45.2 µs ± 7.02 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
np.random.seed(0)
arr = np.random.randint(0,2,100)
arr = arr^(arr&1==arr)
40.3 µs ± 7.8 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
np.random.seed(0)
arr = np.random.randint(0,2,100)
where_1 = np.where(arr == 1)
where_0 = np.where(arr == 0)
arr[where_0] = 1
arr[where_1] = 0
49.1 µs ± 13.4 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
np.random.seed(0)
arr = np.random.randint(0,2,100)
arr = np.where((arr==0)|(arr==1), arr^1, arr)
52.3 µs ± 11.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
inverted = ~arr + 2
,为我解决了这个问题,因为我的数组是 8 位的
“~”运算符将数组中整数的所有位从 0 翻转到 1,反之亦然。例如,如果您有由八位(一个字节)0000 0000 表示的整数 0,则波形符操作 ~0000 0000 会产生值 1111 1111,即整数值 -1,reference
所以如果 a = 0,~a 给出 -1 并且 (~a+2) 给出 1 如果 a = 1,~a 给出 -2 并且 (~a+2) 给出 0
我真的很惊讶之前没有人想到这一点。翻转由 0 和 1 组成的 numpy 数组 (
arr
) 中的值的最简单、最有效的方法就是简单地用 1 减去 numpy 数组。换句话说,执行操作 1 - arr
。这是一个简单的例子:
arr = np.array([1, 0, 1, 1, 0])
1 - arr
array([0, 1, 0, 0, 1])