【发布时间】:2019-10-28 21:07:38
【问题描述】:
假设我有一个 numpy 数组,我想将所有 1 交换为 0,将所有 0 交换为 1(该数组将具有其他值,并且 0 和 1 没有什么特别之处)。当然,我可以循环遍历数组并逐个更改它。您可以推荐使用一种有效的方法吗? np.where() 方法有这个操作的选项吗?
【问题讨论】:
假设我有一个 numpy 数组,我想将所有 1 交换为 0,将所有 0 交换为 1(该数组将具有其他值,并且 0 和 1 没有什么特别之处)。当然,我可以循环遍历数组并逐个更改它。您可以推荐使用一种有效的方法吗? np.where() 方法有这个操作的选项吗?
【问题讨论】:
最棘手的部分是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
【讨论】:
iverted = ~arr + 2 应该做的工作
【讨论】:
the array will have other values。例如,4 将是 -3。
a^(a&1==a)
例如
a = np.arange(-3, 4)
a^(a&1==a)
# array([-3, -2, -1, 1, 0, 2, 3])
【讨论】:
(a&1==a)在这里做了什么:)
一种不需要使用任何特殊方法(例如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])
【讨论】:
这是使用np.where 的一种方法,当它是0 或1 时,取给定值的按位XOR:
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]])
【讨论】:
a^1 太聪明了:-)
^ 做什么的人...
1-a。
a<2 变得更简单/更快,顺便说一句 ;-)
对于 np.where,这是一个不太聪明的选择,只是将它用于索引:
where_0 = np.where(arr == 0)
where_1 = np.where(arr == 1)
arr[where_0] = 1
arr[where_1] = 0
如果您对其他值有更多了解(例如,它们都是小数字),可能会有更多选择,但这是最简单的。
【讨论】:
np.where之外,您还可以使用np.select?