Разбейте numy массивы на подмассивы в соответствии с их признаками - PullRequest
0 голосов
/ 28 февраля 2019

Предположим, у меня есть пустой массив

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

Я хотел бы разбить массив на подмассивы в соответствии с правилом: первый подмассив начинается с [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 голосов
/ 01 марта 2019

Следующая функция разбивает 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)
0 голосов
/ 28 февраля 2019

Вот один из компактных способов вывести список этих подмассивов в качестве выходных данных -

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])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...