>我有一个 2D 数组 A:
28 39 52
77 80 66
7 18 24
9 97 68
和列索引 B 的向量数组:
1
0
2
0
如何以pythonian的方式,使用基本的Python或Numpy,从A中选择与B中的列索引不对应的元素?
我应该得到这个包含 A 元素的 2D 数组,与存储在 B 中的列索引不对应:
28 52
80 66
7 18
97 68
您可以使用广播和逐行掩码为每行选择数组中未包含的元素:
设置
B = np.array([1, 0, 2, 0])
cols = np.arange(A.shape[1])
现在使用广播创建掩码,并为阵列编制索引。
mask = B[:, None] != cols
A[mask].reshape(-1, 2)
array([[28, 52],
[80, 66],
[ 7, 18],
[97, 68]])
我对你另一个问题的回答的衍生品,
使用列索引向量将 2D 数组元素替换为零
我们可以制作一个布尔mask
,索引与之前使用的索引相同:
In [124]: mask = np.ones(A.shape, dtype=bool)
In [126]: mask[np.arange(4), B] = False
In [127]: mask
Out[127]:
array([[ True, False, True],
[False, True, True],
[ True, True, False],
[False, True, True]])
使用布尔掩码索引数组会生成一维数组,因为在最一般的情况下,这种掩码可以在每行中选择不同数量的元素。
In [128]: A[mask]
Out[128]: array([28, 52, 80, 66, 7, 18, 97, 68])
在这种情况下,结果可以改写回 2d:
In [129]: A[mask].reshape(4,2)
Out[129]:
array([[28, 52],
[80, 66],
[ 7, 18],
[97, 68]])
由于您允许"基本Python",因此列表理解答案如下:
In [136]: [[y for i,y in enumerate(x) if i!=b] for b,x in zip(B,A)]
Out[136]: [[28, 52], [80, 66], [7, 18], [97, 68]]
如果其他A
中的所有 0 都来自插入,那么我们也Out[127]
mask
可以用
In [142]: A!=0
Out[142]:
array([[ True, False, True],
[False, True, True],
[ True, True, False],
[False, True, True]])