tril_indices() 可能是这里生成较低三角形索引的明显方法,然后您可以使用这些方法将输入数组中的那些设置为 NaNs。
现在,如果您关心性能,您可以在创建这种下三角形状的蒙版后使用boolean indexing,然后将其设置为NaNs。实现看起来像这样 -
m[np.arange(m.shape[0])[:,None] > np.arange(m.shape[1])] = np.nan
所以,np.arange(m.shape[0])[:,None] > np.arange(m.shape[1]) 是这里使用 broadcasting 创建的掩码。
示例运行 -
In [51]: m
Out[51]:
array([[ 11., 49., 23., 30.],
[ 40., 41., 19., 26.],
[ 32., 36., 30., 25.],
[ 15., 27., 25., 40.],
[ 33., 18., 45., 43.]])
In [52]: np.arange(m.shape[0])[:,None] > np.arange(m.shape[1]) # mask
Out[52]:
array([[False, False, False, False],
[ True, False, False, False],
[ True, True, False, False],
[ True, True, True, False],
[ True, True, True, True]], dtype=bool)
In [53]: m[np.arange(m.shape[0])[:,None] > np.arange(m.shape[1])] = np.nan
In [54]: m
Out[54]:
array([[ 11., 49., 23., 30.],
[ nan, 41., 19., 26.],
[ nan, nan, 30., 25.],
[ nan, nan, nan, 40.],
[ nan, nan, nan, nan]])
运行时测试 -
本部分将本解决方案中列出的基于布尔索引的方法与other solution 中基于np.tril_indices 的方法进行性能比较。
In [38]: m = np.random.randint(10,50,(1000,1100)).astype(float)
In [39]: %timeit m[np.tril_indices(m.shape[0], -1)] = np.nan
10 loops, best of 3: 62.8 ms per loop
In [40]: m = np.random.randint(10,50,(1000,1100)).astype(float)
In [41]: %timeit m[np.arange(m.shape[0])[:,None] > np.arange(m.shape[1])] = np.nan
100 loops, best of 3: 8.03 ms per loop