Python/Numpy 填充非连续点之间的间隙

2024-10-06 18:30:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图找到一种矢量化/快速/数字友好的方法,将a列中的以下值转换为B列:

ID  A   B
1   0   0
2   0   0
3   1   0
4   1   1
5   0   1
6   0   1
7   -1  1
8   0   0
9   1   0
10  0   1
11  0   1
12  1   1
13  0   1
14  -1  1
15  0   0

定义列“B”的算法是用值1填充1和-1组之间的所有间隙,跳过每对中的第一行。也就是说,对于ID4-ID7,B列填充1(给定A@ID3列中的首字母1)。接下来,从ID10-ID14填充1(因为A列@ID9=1)。在

虽然使用for循环很容易实现,但我想知道是否存在非循环解决方案?基于O(n)循环的解决方案如下:

^{pr2}$

以上函数在我的机器上产生以下性能:

%timeit y = make_y(x)
10000 loops, best of 3: 28 µs per loop

我想肯定有某种方法可以让整个过程更快,因为我最终将需要处理一千万个以上元素长的数组。。。在


Tags: 方法算法id定义数字解决方案矢量化id3
2条回答

这个很好

A=[0,0,1,1,0,0,-1,0,1,0,0,1,0,-1,0]
B=[]
#initializing column with same number of zeros 
for j in range(len(A)):
    B.append(0)
print A
for i in range(len(A)):
    #retrieve the indices of pair (1 to -1)
    try:
            one_index=A.index(1)
            neg_one_index=A.index(-1)
    except:
            pass 
    one_index=one_index+1
    #replacing the zeros in column B by 1 at correct locations
    while one_index<=neg_one_index:
            B[one_index]=1
            A[one_index-1]=0
            A[one_index]=0
            one_index=one_index+1
print B
#output->[0,0,0,1,1,1,1,0,0,1,1,1,1,1,0] (i.e correct)

可能的矢量化解决方案如下

idx_1s, = np.where(x == -1)  # find the positions of the -1's
idx1s, = np.where(x == 1)  # find the positions of the 1's

要找到哪些1应该变成0,并标记1块的开始:

^{pr2}$

现在我们有两个长度相等的数组,idx0sidx_1s,标记每个块的第一项和最后一项的位置,因此我们现在可以:

y = x.copy()
y[idx0s] = 0
idx0s += 1
idx_1s += 1
mask = np.zeros_like(y, dtype=np.bool)
mask[idx0s] = True
mask[idx_1s] = True
mask = np.logical_xor.accumulate(mask)
y[mask] = 1

从而产生所需的:

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

对于格式错误的输入,它可能有点脆弱,而且我认为它不能优雅地处理尾部-1。但是唯一的非O(n)操作是对searchsorted的调用,但是searchsorted进行了优化,可以更快地搜索已排序的键,因此它可能不会很明显。在

如果我在你的x上计算时间,它不会超过循环版本,但对于更大的数组,它可能会。在

相关问题 更多 >