Определить двоичное состояние набора данных (частота вкл / выкл)

У меня большой набор данных со значениями в диапазоне [-3,3], и я использую жесткий предел в 0 в качестве границы.

Данные имеют двоичное значение 1, когда они колеблются от -3,3 на частоте 56 кГц. Это означает, что данные будут изменяться с -3 на 3 и возвращаться через каждые N значений данных, где N обычно < 20.

Данные имеют двоичное значение 0, когда данные постоянно равны 3 (обычно это может длиться более 400 сэмплов)

Кажется, я не могу сгруппировать данные в двоичные категории, а также знаю, сколько выборок в группе.

Пример данных:

1.84    |
2.96    |
2.8     |
3.12    |
.       |  I want this to be grouped as a 0
.       |
3.11    |_____
-3.42   |
-2.45   |
-1.49   |
3.12    |
2.99    |  I want this to be grouped as a 1
1.97    |
-1.11   |
-2.33   |
.       |  
.       |  Keeps going until for N cycles

Циклы между логическим состоянием HIGH обычно малы (<20 выборок).

Код у меня так далеко:

state = "X"
for i in range(0, len(data['input'])):    
    currentBinaryState = inputBinaryState(data['input'][i]); # Returns -3 or +3 appropriately

    if(currentBinaryState != previousBinaryState):

        # A cycle is very unlikely to last more than 250 samples
        if y > 250 and currentBinaryState == "LOW": # Been low for a long time
            if state == "_high":
                groupedData['input'].append( ("HIGH", x) )
                x = 0

            state = "_low"

        else:
            # Is on carrier wave (logic 1)
            if state == "_low":
                # Just finished low
                groupedData['input'].append( ("LOW", x) )
                x = 0

            state = "_high"


        y = 0

Очевидно, что результат не такой, как я должен ожидать, поскольку группа LOW очень мала.

[('HIGH', 600), ('LOW', 8), ('HIGH', 1168), ('LOW', 9), ('HIGH', 1168), ('LOW', 8), ('HIGH', 1168), ('LOW', 8), ('HIGH', 1168), ('LOW', 9), ('HIGH', 1168), ('LOW', 8), ('HIGH', 1168), ('LOW', 8), ('HIGH', 1168), ('LOW', 9)]

Я понимаю, что мог спросить об этом в SA обработки сигналов, но я счел эту проблему более ориентированной на программирование. Я надеюсь, что объяснил проблему достаточно, если есть какие-либо вопросы, просто задайте. Благодарю.


Вот ссылка на фактические данные образца:

https://drive.google.com/folderview?id=0ByJDNIfaTeEfemVjSU9hNkNpQ3c&usp=sharing

Визуально очень ясно, где лежат границы данных. Участок образца данных


Обновление 1

Я обновил свой код, чтобы сделать его более разборчивым, так как переменные, состоящие из одной буквы, не помогают мне в здравом уме

previousBinaryState = "X"
x = 0
sinceLastChange = 0
previousGroup = inputBinaryState(data['input'][0])
lengthAssert = 0
for i in range(0, len(data['input'])):    
    currentBinaryState = inputBinaryState(data['input'][i]);

    if(currentBinaryState != previousBinaryState): # Changed from -3 -> +3 or +3 -> -3 

        #print sinceLastChange

        if sinceLastChange > 250 and previousGroup == "HIGH" and currentBinaryState == "LOW": # Finished LOW group
            groupedData['input'].append( ("LOW", x) )
            lengthAssert += x
            x = 0
            previousGroup = "LOW"

        elif sinceLastChange > 20 and previousGroup == "LOW": # Finished HIGH group
            groupedData['input'].append( ("HIGH", x) )
            lengthAssert += x
            x = 0
            previousGroup = "HIGH"

        sinceLastChange = 0

    else:
        sinceLastChange += 1

    previousBinaryState = currentBinaryState
    x += 1  

Который, для данных примера, выводит:

8
7
8
7
7
596   <- Clearly a LOW group
7
8
7
8
7
7
8
7
8
7
7
8
7
8
7
7
8
7
8
.
.
.

Проблема в том, что группа HIGH длится дольше, чем она должна быть:

[('HIGH', 600), ('LOW', 1176), ('HIGH', 1177), ('LOW', 1176), ('HIGH', 1176), ('LOW', 1177), ('HIGH', 1176), ('LOW', 1176)]
  • Всего сделано 8 групп, но сюжет явно показывает гораздо больше. Похоже, что группы в два раза больше, чем должны быть.

1 ответ

Решение

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

Он не подберет последнюю группу в наборе данных, но это нормально.

previousBinaryState = "X"
x = 0
sinceLastChange = 0
previousGroup = inputBinaryState(data['input'][0])
lengthAssert = 0
for i in range(0, len(data['input'])):    
    currentBinaryState = inputBinaryState(data['input'][i]);

    if(currentBinaryState != previousBinaryState): # Changed from -3 -> +3 or +3 -> -3 

        #print sinceLastChange

        if sinceLastChange > 250 and previousGroup == "HIGH" and currentBinaryState == "LOW": # Finished LOW group
            groupedData['input'].append( ("LOW", x) )
            lengthAssert += x
            x = 0
            previousGroup = "LOW"

        sinceLastChange = 0

    else:
        if sinceLastChange > 20 and previousGroup == "LOW":
            groupedData['input'].append( ("HIGH", x) )
            lengthAssert += x
            x = 0
            previousGroup = "HIGH"
            sinceLastChange = 0

        sinceLastChange += 1

    previousBinaryState = currentBinaryState
    x += 1           

20 - максимальное количество циклов в состоянии HIGH, а 250 - максимальное количество выборок, для которых группа находится в состоянии LOW.

[('HIGH', 25), ('LOW', 575), ('HIGH', 602), ('LOW', 574), ('HIGH', 602), ('LOW', 575), ('HIGH', 601), ('LOW', 575), ('HIGH', 602), ('LOW', 574), ('HIGH', 602), ('LOW', 575), ('HIGH', 601), ('LOW', 575), ('HIGH', 602), ('LOW', 574)]

Сравнивая это с графиком и фактическими данными, это кажется правильным.

Другие вопросы по тегам