仅按第一个位置创建遮罩
Create mask by first positions only
我有数组:
a = np.array([[ 0, 1, 2, 0, 0, 0],
[ 0, 4, 1, 35, 0, 10],
[ 0, 0, 5, 4, 0, 4],
[ 1, 2, 5, 4, 0, 4]])
我只需要 select 每行中第一个连续的 0
:
[[ True False False False False False]
[ True False False False False False]
[ True True False False False False]
[ False False False False False False]]
我试试:
a[np.arange(len(a)), a.argmax(1): np.arange(len(a)), [0,0,0]] = True
但这是错误的。
您可以使用 np.cumsum
.
假设:您只在每行的开头查找零。
a = np.array([[ 0, 1, 2, 0, 0, 0],
[ 0, 4, 1, 35, 0, 10],
[ 0, 0, 5, 4, 0, 4]])
a.cumsum(axis=1) == 0
array([[ True, False, False, False, False, False],
[ True, False, False, False, False, False],
[ True, True, False, False, False, False]], dtype=bool)
基础:只要每行的累计和为 0,就保持 True
。
容易出错:带有负整数的数组会导致失败。 IE。对于 [-1, 1]
,这将在位置 1 处计算为 True
。
您可以使用 np.minimum.accumulate
条件测试 a == 0
(在行上);由于非零给出 False
,因此第一个非零之后的元素将被设置为 False
由于累积最小值:
np.minimum.accumulate(a == 0, axis=1)
#array([[ True, False, False, False, False, False],
# [ True, False, False, False, False, False],
# [ True, True, False, False, False, False],
# [False, False, False, False, False, False]], dtype=bool)
这是 argmin
+ broadcasting
-
(a==0).argmin(1)[:,None] > np.arange(a.shape[1])
带示例的逐步解释 运行
1) 输入数组:
In [207]: a
Out[207]:
array([[ 0, 1, 2, 0, 0, 0],
[ 0, 4, 1, 35, 0, 10],
[ 0, 0, 5, 4, 0, 4],
[ 1, 2, 5, 4, 0, 4]])
2) 零掩码
In [208]: (a==0)
Out[208]:
array([[ True, False, False, True, True, True],
[ True, False, False, False, True, False],
[ True, True, False, False, True, False],
[False, False, False, False, True, False]], dtype=bool)
3) 获取出现 False 的索引,表示每一行的第一个 True 岛结束。因此,对于任何没有零的行,或者如果第一个元素不为零,将导致 argmin 输出为 0
。因此,我们的下一个任务是使用 broadcasting
创建一个从第一行开始为 True 并在 argmin
索引处停止为 True 的掩码。这将是 broadcasted-comparison
针对范围数组扩展覆盖所有列的一个。
In [209]: (a==0).argmin(1)
Out[209]: array([1, 1, 2, 0])
In [210]: (a==0).argmin(1)[:,None] > np.arange(a.shape[1])
Out[210]:
array([[ True, False, False, False, False, False],
[ True, False, False, False, False, False],
[ True, True, False, False, False, False],
[False, False, False, False, False, False]], dtype=bool)
计时
In [196]: a = np.random.randint(0,9,(5000,5000))
In [197]: %timeit a.cumsum(axis=1) == 0 #@Brad Solomon
...: %timeit np.minimum.accumulate(a == 0, axis=1) #@Psidom
...: %timeit (a==0).argmin(1)[:,None] > np.arange(a.shape[1])
...:
10 loops, best of 3: 69 ms per loop
10 loops, best of 3: 64.9 ms per loop
10 loops, best of 3: 32.8 ms per loop
我有数组:
a = np.array([[ 0, 1, 2, 0, 0, 0],
[ 0, 4, 1, 35, 0, 10],
[ 0, 0, 5, 4, 0, 4],
[ 1, 2, 5, 4, 0, 4]])
我只需要 select 每行中第一个连续的 0
:
[[ True False False False False False]
[ True False False False False False]
[ True True False False False False]
[ False False False False False False]]
我试试:
a[np.arange(len(a)), a.argmax(1): np.arange(len(a)), [0,0,0]] = True
但这是错误的。
您可以使用 np.cumsum
.
假设:您只在每行的开头查找零。
a = np.array([[ 0, 1, 2, 0, 0, 0],
[ 0, 4, 1, 35, 0, 10],
[ 0, 0, 5, 4, 0, 4]])
a.cumsum(axis=1) == 0
array([[ True, False, False, False, False, False],
[ True, False, False, False, False, False],
[ True, True, False, False, False, False]], dtype=bool)
基础:只要每行的累计和为 0,就保持 True
。
容易出错:带有负整数的数组会导致失败。 IE。对于 [-1, 1]
,这将在位置 1 处计算为 True
。
您可以使用 np.minimum.accumulate
条件测试 a == 0
(在行上);由于非零给出 False
,因此第一个非零之后的元素将被设置为 False
由于累积最小值:
np.minimum.accumulate(a == 0, axis=1)
#array([[ True, False, False, False, False, False],
# [ True, False, False, False, False, False],
# [ True, True, False, False, False, False],
# [False, False, False, False, False, False]], dtype=bool)
这是 argmin
+ broadcasting
-
(a==0).argmin(1)[:,None] > np.arange(a.shape[1])
带示例的逐步解释 运行
1) 输入数组:
In [207]: a
Out[207]:
array([[ 0, 1, 2, 0, 0, 0],
[ 0, 4, 1, 35, 0, 10],
[ 0, 0, 5, 4, 0, 4],
[ 1, 2, 5, 4, 0, 4]])
2) 零掩码
In [208]: (a==0)
Out[208]:
array([[ True, False, False, True, True, True],
[ True, False, False, False, True, False],
[ True, True, False, False, True, False],
[False, False, False, False, True, False]], dtype=bool)
3) 获取出现 False 的索引,表示每一行的第一个 True 岛结束。因此,对于任何没有零的行,或者如果第一个元素不为零,将导致 argmin 输出为 0
。因此,我们的下一个任务是使用 broadcasting
创建一个从第一行开始为 True 并在 argmin
索引处停止为 True 的掩码。这将是 broadcasted-comparison
针对范围数组扩展覆盖所有列的一个。
In [209]: (a==0).argmin(1)
Out[209]: array([1, 1, 2, 0])
In [210]: (a==0).argmin(1)[:,None] > np.arange(a.shape[1])
Out[210]:
array([[ True, False, False, False, False, False],
[ True, False, False, False, False, False],
[ True, True, False, False, False, False],
[False, False, False, False, False, False]], dtype=bool)
计时
In [196]: a = np.random.randint(0,9,(5000,5000))
In [197]: %timeit a.cumsum(axis=1) == 0 #@Brad Solomon
...: %timeit np.minimum.accumulate(a == 0, axis=1) #@Psidom
...: %timeit (a==0).argmin(1)[:,None] > np.arange(a.shape[1])
...:
10 loops, best of 3: 69 ms per loop
10 loops, best of 3: 64.9 ms per loop
10 loops, best of 3: 32.8 ms per loop