gpt4 book ai didi

python - 在 2D NumPy 数组中将每列岛屿缩放到它们的长度

转载 作者:太空宇宙 更新时间:2023-11-03 15:44:29 24 4
gpt4 key购买 nike

例如,我有一个像这样的 numpy 数组:

array([[0,  0,  0,  1,  0,  1],
[0, 0, 0, 1, 0, 1],
[1, 1, 1, 1, 0, 1],
[1, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 1, 0],
[1, 1, 0, 0, 0, 1]])

我想在每列中找到值 1 的连续像素,并将这些像素值设置为获得的长度,以获得此输出:

array([[0,  0,  0,  3,  0,  4],
[0, 0, 0, 3, 0, 4],
[2, 1, 1, 3, 0, 4],
[2, 0, 0, 0, 2, 4],
[0, 0, 0, 0, 2, 0],
[1, 1, 0, 0, 0, 1]])

谢谢你的帮助

最佳答案

方法 #1

def scaleby_grouplen(ar):
a = ar==1
a1 = np.pad(a, ((1, 1), (0, 0)), 'constant')
a2 = a1.ravel('F')
idx = np.flatnonzero(a2[1:] != a2[:-1])
start, stop = idx[::2], idx[1::2]
id_ar = np.zeros(len(a2), dtype=int)
id_ar[start+1] = 1
idx_ar = id_ar.cumsum()-1
lens = stop - start
out = a*lens[idx_ar].reshape(-1,a.shape[0]+2).T[1:-1]
return out

方法 #2

或者,利用 np.maximum.accumulate 替换 cumsum 部分 -

def scaleby_grouplen_v2(ar):
a = ar==1
a1 = np.pad(a, ((1, 1), (0, 0)), 'constant')
a2 = a1.ravel('F')
idx = np.flatnonzero(a2[1:] != a2[:-1])
start, stop = idx[::2], idx[1::2]
id_ar = np.zeros(len(a2), dtype=int)
id_ar[start+1] = np.arange(len(start))
idx_ar = np.maximum.accumulate(id_ar)
lens = stop - start
out = a*lens[idx_ar].reshape(-1,a.shape[0]+2).T[1:-1]
return out

方法 #3

使用 np.repeat 重复组长度并因此填充 -

def scaleby_grouplen_v3(ar):
a = ar==1
a1 = np.pad(a, ((1, 1), (0, 0)), 'constant')
a2 = a1.ravel('F')
idx = np.flatnonzero(a2[1:] != a2[:-1])
lens = idx[1::2] - idx[::2]
out = ar.copy()
out.T[a.T] = np.repeat(lens, lens)
return out

sample 运行-

In [177]: a
Out[177]:
array([[0, 0, 0, 1, 0, 1],
[0, 0, 0, 1, 0, 1],
[1, 1, 1, 1, 0, 1],
[1, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 1, 0],
[1, 1, 0, 0, 0, 1]])

In [178]: scaleby_grouplen(a)
Out[178]:
array([[0, 0, 0, 3, 0, 4],
[0, 0, 0, 3, 0, 4],
[2, 1, 1, 3, 0, 4],
[2, 0, 0, 0, 2, 4],
[0, 0, 0, 0, 2, 0],
[1, 1, 0, 0, 0, 1]])

基准测试

其他方法-

from numpy import array
from itertools import chain, groupby

# @timgeb's soln
def chain_groupby(a):
groups = (groupby(col, bool) for col in a.T)
unrolled = ([(one, list(sub)) for one, sub in grp] for grp in groups)
mult = ([[x*len(sub) for x in sub] if one else sub for one, sub in grp] for grp in unrolled)
chained = [list(chain(*sub)) for sub in mult]
result = array(chained).T
return result

时间 -

In [280]: np.random.seed(0)

In [281]: a = np.random.randint(0,2,(1000,1000))

In [282]: %timeit chain_groupby(a)
1 loop, best of 3: 667 ms per loop

In [283]: %timeit scaleby_grouplen(a)
100 loops, best of 3: 17.7 ms per loop

In [284]: %timeit scaleby_grouplen_v2(a)
100 loops, best of 3: 17.1 ms per loop

In [331]: %timeit scaleby_grouplen_v3(a)
100 loops, best of 3: 18.6 ms per loop

关于python - 在 2D NumPy 数组中将每列岛屿缩放到它们的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50833792/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com