方法#1
这是一种矢量化 NumPy 方法,可将这些行索引分组到数组列表中 -
r,c = np.where(arr.T)
out = np.split(c, np.flatnonzero(r[1:] != r[:-1])+1)
示例运行 -
In [63]: arr = np.random.randint(2, size=15).reshape((3,5)).astype(bool)
In [64]: arr
Out[64]:
array([[False, False, True, True, False],
[ True, True, False, False, True],
[ True, True, False, False, True]], dtype=bool)
In [65]: r,c = np.where(arr.T)
In [66]: np.split(c, np.flatnonzero(r[1:] != r[:-1])+1)
Out[66]: [array([1, 2]), array([1, 2]), array([0]), array([0]), array([1, 2])]
In [67]: calc(arr)
Out[67]: [[1, 2], [1, 2], [0], [0], [1, 2]]
方法 #2
或者,我们可以使用loop comprehension 来避免这种分裂 -
idx = np.concatenate(([0], np.flatnonzero(r[1:] != r[:-1])+1, [r.size] ))
out = [c[idx[i]:idx[i+1]] for i in range(len(idx)-1)]
我们使用方法#1 中的r,c。
方法 #3(为所有 0 列输出空列表/数组)
为了考虑全零列,我们需要空列表/数组,这是一种修改后的方法 -
idx = np.concatenate(([0], arr.sum(0).cumsum() ))
out = [c[idx[i]:idx[i+1]] for i in range(len(idx)-1)]
我们正在使用方法#1 中的c。
示例运行 -
In [177]: arr
Out[177]:
array([[ True, False, False, False, False],
[ True, False, False, False, True],
[ True, False, True, False, True]], dtype=bool)
In [178]: idx = np.concatenate(([0], arr.sum(0).cumsum() ))
...: out = [c[idx[i]:idx[i+1]] for i in range(len(idx)-1)]
...:
In [179]: out
Out[179]:
[array([0, 1, 2]),
array([], dtype=int64),
array([2]),
array([], dtype=int64),
array([1, 2])]
方法#4
这是处理所有0s cols 的另一种方法-
unq, IDs = np.unique(r, return_index=1)
idx = np.concatenate(( IDs, [r.size] ))
out = [[]]*arr.shape[1]
for i,item in enumerate(unq):
out[item] = c[idx[i]:idx[i+1]]
我们正在使用方法 #1 中的r,c。