根据符号将numpy数组分为子数组

时间:2019-02-28 20:38:49

标签: python numpy

假设我有一个numpy数组

a = numpy.array( [-1, -2, 3, 3, -4, -4, 9, 9, 10, -1, -3] ).

我想根据规则将数组分成多个子数组:第一个子数组以a [0]开头,并在其改变符号之前结束。我们在最后一个操作结束的地方继续该过程。

例如,示例中的数组将细分为子数组:

a1 = numpy.array( [-1, -2] )
a2 = numpy.array( [3, 3] )
a3 = numpy.array( [-4, -4] )
a4 = numpy.array( [9, 9, 10] )
a5 = numpy.array( [-1, -3] )

我考虑过将遮罩与结合使用并不能很好地实现。

2 个答案:

答案 0 :(得分:3)

这是一种产生这些子数组列表作为输出的紧凑方法-

In [170]: a
Out[170]: array([-1, -2,  3,  3, -4, -4,  9,  9, 10, -1, -3])

In [171]: np.split(a,np.flatnonzero(np.diff(a>0))+1)
Out[171]: 
[array([-1, -2]),
 array([3, 3]),
 array([-4, -4]),
 array([ 9,  9, 10]),
 array([-1, -3])]

或者,masking可以提高效率-

In [172]: mask = a>0

In [173]: np.split(a,np.flatnonzero(mask[:-1] != mask[1:])+1)
Out[173]: 
[array([-1, -2]),
 array([3, 3]),
 array([-4, -4]),
 array([ 9,  9, 10]),
 array([-1, -3])]

如果以不同的符号表示您打算将0s单独分组,请在组合中使用np.sign-

In [272]: a
Out[272]: array([ 4,  0, -4,  3, -4, -4,  9,  9, 10, -1, -3])

In [273]: np.split(a,np.flatnonzero(np.diff(np.sign(a))!=0)+1)
Out[273]: 
[array([4]),
 array([0]),
 array([-4]),
 array([3]),
 array([-4, -4]),
 array([ 9,  9, 10]),
 array([-1, -3])]

创建标记的岛屿

根据分组创建标记的岛屿-

mask = a>0
label = (np.ediff1d(mask.astype(int),to_begin=mask[0])!=0).cumsum()-mask[0]

样品运行-

# input array starting with negative number
In [243]: a
Out[243]: array([-1, -2,  3,  3, -4, -4,  9,  9, 10, -1, -3])

In [244]: mask = a>0

In [246]: (np.ediff1d(mask.astype(int),to_begin=mask[0])!=0).cumsum()-mask[0]
Out[246]: array([0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4])

# input array starting with positive number
In [248]: a
Out[248]: array([ 1, -2,  3,  3, -4, -4,  9,  9, 10, -1, -3])

In [249]: mask = a>0

In [251]: (np.ediff1d(mask.astype(int),to_begin=mask[0])!=0).cumsum()-mask[0]
Out[251]: array([0, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5])

答案 1 :(得分:0)

以下函数分割a,返回list的必需子{numpy.array s

import numpy as np

def splitBySign(arr):
    arrSign = np.sign(arr)                              # array([-1, -1,  1,  1, -1, -1,  1,  1,  1, -1, -1])
    arrSignChange = arrSign[:-1] - arrSign[1:]          # array([ 0, -2,  0,  2,  0, -2,  0,  0,  2,  0])
    splitIndices = np.nonzero(arrSignChange)[0] + 1     # array([2, 4, 6, 9])
    startIndices = np.insert(splitIndices, 0, 0)        # array([0, 2, 4, 6, 9])
    endIndices = np.append(splitIndices, len(arr))      # array([ 2,  4,  6,  9, 11])
    subArrList = []
    for start, end in zip(startIndices, endIndices):
        subArr = arr[start:end]
        subArrList.append(subArr)

    return subArrList                                   # [array([-1, -2]), array([3, 3]), array([-4, -4]), array([ 9,  9, 10]), array([-1, -3])]

为了更好地理解,将其局部变量的值作为注释提供,以如下方式用给定的arr调用参数a

arr = np.array([-1, -2, 3, 3, -4, -4, 9, 9, 10, -1, -3])
subArrList = splitBySign(a)