Как разбить список с помощью двух вложенных условий - PullRequest
0 голосов
/ 28 мая 2020

Обычно у меня есть список 0 s и 1 s. Каждое значение в списке представляет собой образец данных за час. Таким образом, если в списке 24 0 s и 1 s, это означает, что есть 24 часа или один день. Я хочу в первый раз зафиксировать циклы данных от 0 s до 1 s обратно до 0 s в течение 24 часов (или наоборот, от 1 s до 0 s обратно до 1 s).

signal = [1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1]

ожидаемый результат:

#                                                     D   
signal = [1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0]
output = [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
#                           ^ cycle.1:day.1           |dayline        ^cycle.1:day.2

В списке вывода, когда есть 1, это означает, что 1 цикл завершен в этой позиции списка сигналов и в состоянии покоя позиции есть 0. В днях должен быть только 1 цикл, поэтому там только 1.

Я не знаю, как разбить этот список в соответствии с этим, так может ли кто-нибудь помочь?

1 Ответ

1 голос
/ 28 мая 2020

Мне кажется, что вы пытаетесь сначала разбить данные на блоки по 24, а затем найти либо первый нарастающий фронт, либо первый спадающий фронт в зависимости от первого часа в этом блоке.

Ниже я попытался выразить свое понимание того, что вы пытаетесь выполнить, sh в следующей функции. Он принимает numpy.array, содержащий нули и единицы, как в вашем примере. Он проверяет, что такое первый час дня, и решает, какой тип края искать. он обнаруживает край, используя np.diff. Это дает нам массив, содержащий -1, 0 и 1. Затем мы ищем первый индекс спадающего фронта -1 или переднего фронта 1. Функция возвращает этот индекс или, если ребер не было обнаружено, возвращает индекс последнего элемента или ничего.

Подробнее см. В документации описание используемых здесь функций numpy np.diff, np.array.nonzero, np.array_split

import numpy as np

def get_cycle_index(day):
    '''
    returns the first index of a cycle defined by nipun vats
    if no cycle is found returns nothing
    '''

    first_hour = day[0]
    if first_hour == 0:
        edgetype = -1
    else:
        edgetype = 1

    edges = np.diff(np.r_[day, day[-1]])

    if (edges == edgetype).any():
        return (edges == edgetype).nonzero()[0][0]
    elif (day.sum() == day.size) or day.sum() == 0:
        return
    else:
        return day.size - 1

Ниже приведен пример того, как вы можете использовать эту функцию в вашем случае.

import numpy as np

_data = [1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
#_data = np.random.randint(0,2,280, dtype='int')
data = np.array(_data, 'int')

#split the data into a set of 'day' blocks
blocks = np.array_split(data, np.arange(24,data.size, 24))


_output = []

for i, day in enumerate(blocks):
    print(f'day {i}')
    buffer = np.zeros(day.size, dtype='int')
    print('\tsignal:', *day, sep = ' ')
    cycle_index = get_cycle_index(day)
    if cycle_index:
        buffer[cycle_index] = 1
    print('\toutput:', *buffer, sep=' ')

    _output.append(buffer)

output = np.concatenate(_output)
print('\nfinal output:\n', *output, sep=' ')

это дает следующий результат:

day 0
    signal: 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0
    output: 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
day 1
    signal: 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    output: 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
day 2
    signal: 0 0 0 0 0 0
    output: 0 0 0 0 0 0

final output:
 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...