使用NumPy在非零元素值相同的情况下,将数组中位于非零元素之间的零值填充为相同的值。

4

我有一个包含整数的一维numpy数组,我希望将其中的零替换为前一个非零值,但仅当下一个非零值与之相同时。

例如,一个数组:

in: x = np.array([1,0,1,1,0,0,2,0,3,0,0,0,3,1,0,1])
out: [1,0,1,1,0,0,2,0,3,0,0,0,3,1,0,1]

应该变成:

out: [1,1,1,1,0,0,2,0,3,3,3,3,3,1,1,1]

有没有向量化的方法来实现这个?我找到了一些填充零值的方法在这里,但没有找到如何处理异常情况,即不填充具有不同值的整数中的零值。

1
什么是异常?你有非数字值吗? - roganjosh
我的意思是,当使用iff语句时,不要用不同的值填充整数中的零。 - Bram Zijlstra
1
啊哈,好的,我是指编程异常,而不是规则例外。抱歉。 - roganjosh
1
@BramZijlstra 这种情况是否总是只有一个零在相同元素之间,例如 [1, 0, 1..., 3, 0, 3, ..., 1,0,1] - kmario23
不,可能会出现多个零。 - Bram Zijlstra
1个回答

4
这里提供了一个向量化的方法,灵感来自于基于NumPy的前向填充。这个解决方案结合了"掩码"和"切片",用于实现前向填充部分。
def forward_fill_ifsame(x):
    # Get mask of non-zeros and then use it to forward-filled indices
    mask = x!=0
    idx = np.where(mask,np.arange(len(x)),0)
    np.maximum.accumulate(idx,axis=0, out=idx)

    # Now we need to work on the additional requirement of filling only
    # if the previous and next ones being same
    # Store a copy as we need to work and change input data
    x1 = x.copy()

    # Get non-zero elements
    xm = x1[mask]

    # Off the selected elements, we need to assign zeros to the previous places
    # that don't have their correspnding next ones different
    xm[:-1][xm[1:] != xm[:-1]] = 0

    # Assign the valid ones to x1. Invalid ones become zero.
    x1[mask] = xm

    # Use idx for indexing to do the forward filling
    out = x1[idx]

    # For the invalid ones, keep the previous masked elements
    out[mask] = x[mask]
    return out

样例运行 -

In [289]: x = np.array([1,0,1,1,0,0,2,0,3,0,0,0,3,1,0,1])

In [290]: np.vstack((x, forward_fill_ifsame(x)))
Out[290]: 
array([[1, 0, 1, 1, 0, 0, 2, 0, 3, 0, 0, 0, 3, 1, 0, 1],
       [1, 1, 1, 1, 0, 0, 2, 0, 3, 3, 3, 3, 3, 1, 1, 1]])

In [291]: x = np.array([1,0,1,1,0,0,2,0,3,0,0,0,1,1,0,1])

In [292]: np.vstack((x, forward_fill_ifsame(x)))
Out[292]: 
array([[1, 0, 1, 1, 0, 0, 2, 0, 3, 0, 0, 0, 1, 1, 0, 1],
       [1, 1, 1, 1, 0, 0, 2, 0, 3, 0, 0, 0, 1, 1, 1, 1]])

In [293]: x = np.array([1,0,1,1,0,0,2,0,3,0,0,0,1,1,0,2])

In [294]: np.vstack((x, forward_fill_ifsame(x)))
Out[294]: 
array([[1, 0, 1, 1, 0, 0, 2, 0, 3, 0, 0, 0, 1, 1, 0, 2],
       [1, 1, 1, 1, 0, 0, 2, 0, 3, 0, 0, 0, 1, 1, 0, 2]])

1
@Divakar 当我学习张量分解时,其中一个任务是分析人们通常用于超链接页面的术语。 这是使用真实数据集完成的。 分析结果并不好。 因为几乎总是使用“在这里看”,“在此帖子中”,“另一个博客”,“在此链接”等术语,这些术语并不那么有趣。 因此,在超链接时,最好使用问题主题。即,以 “填充NaN值的最有效方式” 作为链接标题,这应该使链接标题具有信息性 :) 并且也更加美观。 - kmario23
1
@Divakar,你总是用你的理解看似复杂的需求和找到简单直接、可能最有效的解决方案来激励我。 - Siraj S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接