В данном уроке мы рассмотри простой способ фильтрации полученных данных.
Предположим вы делаете измерение некой величины, при чем устройство работает в условиях помех: самое простое это измерения напряжения в бортовой сети машины. При измерении может пройти помеха в виде не верной величины, и нам нужно ее убрать.
Самое простое, это сделать N измерений, поместить их в массив, отсортировать и убрать первые и последние значения. Если не вдаваться в глубокую теорию, то как раз первые и последние значения в массиве будут максимально отдалены от истинных значений. Количество значений в массиве и количество элементов которые убираем из массива индивидуально и зависит от вида и условий измерений. У нас будет выборка из 20 измерений и будем убирать по 3 значения слева и справа массива.
В качестве сортирования данных мы используем пузырьковый алгоритм сортировки, который основан на принципе сравнения и обмена пары соседних элементов до тех пор, пока не будут отсортированы все элементы. Скорость у него не большая, зато он очень прост в реализации и подходит для небольших массивов.
Программа реализации пузырькового алгоритма сортировки:
import utime
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
print (list)
def summa (num, z):
for i in range(z):
list.pop(0)
list.pop()
sum=0
for i in range(len(num) - 1):
sum +=list[i]
sum /= (len(list) - 1)
return sum
def bubble_sort(num):
# Устанавливаем sw в True, для запуска цикл минимум один раз
sw = True
while sw:
sw = False
for i in range(len(num) - 1):
if num[i] > num[i + 1]:
# Меняем элементы
num[i], num[i + 1] = num[i + 1], num[i]
# Устанавливаем sw в True для следующей итерации
sw = True
# запуск алгоритма
t1 = utime.ticks_us()
bubble_sort(list)
print (list)
rez=summa (list, 3)
t2 = utime.ticks_us()
temp = (t2 - t1)
print (list)
print('Sum_bubble= %f' % rez)
print('T_bubble= %uus' % temp)
Что же мы написали:
t1 = utime.ticks_us()
Мы фиксируем время начала измерения, в конце выполнения всего алгоритма мы фиксируем время окончания измерения, и высчитываем время которое ушло на выполнение данного алгоритма:
t2 = utime.ticks_us()
temp = (t2 - t1)
import utime
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
print (list)
def selection_sort(num):
# Значение i соответствует кол-ву отсортированных значений
for i in range(len(num)):
# Исходно считаем наименьшим первый элемент
index = i
# Этот цикл перебирает несортированные элементы
for j in range(i + 1, len(num)):
if num[j] < num[index]:
index = j
# Самый маленький элемент меняем с первым в списке
num[i], num[index] = num[index], num[i]
t1 = utime.ticks_us()
selection_sort(list)
rez1=summa (list, 3)
t2 = utime.ticks_us()
temp1 = (t2 – t1)
#print(‘Sum_selection=%f’ % rez1)
#print(‘T_selection=%uus’ % temp1)
import utime
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
print (list)
def insertion_sort(num):
# Сортировку начинаем со второго элемента, т.к. считается, что первый элемент уже отсортирован
for i in range(1, len(num)):
insert = num[i]
# Сохраняем ссылку на индекс предыдущего элемента
j = i – 1
# Элементы отсортированного сегмента перемещаем вперёд, если они больше
# элемента для вставки
while j >= 0 and num[j] > insert:
num[j + 1] = num[j]
j -= 1
# Вставляем элемент
num[j + 1] = insert
t1 = utime.ticks_us()
insertion_sort(list)
rez2=summa (list, 3)
t2 = utime.ticks_us()
temp2 = (t2 – t1)
#print(‘Sum_selection=%f’ % rez2)
#print(‘T_selection=%uus’ % temp2)
import utime
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
print (list)
def heapify(num, heap_size, root_index):
# Индекс наибольшего элемента считаем корневым индексом
largest = root_index
left_child = (2 * root_index) + 1
right_child = (2 * root_index) + 2
# Если левый потомок корня — допустимый индекс, а элемент больше,
# чем текущий наибольший, обновляем наибольший элемент
if left_child < heap_size and num[left_child] > num[largest]:
largest = left_child
# То же самое для правого потомка корня
if right_child < heap_size and num[right_child] > num[largest]:
largest = right_child
# Если наибольший элемент больше не корневой, они меняются местами
if largest != root_index:
num[root_index], num[largest] = num[largest], num[root_index]
# Heapify the new root element to ensure it’s the largest
heapify(num, heap_size, largest)
def heap_sort(num):
n = len(num)
# Создаём Max Heap из списка
# Второй аргумент означает остановку алгоритма перед элементом -1, т.е.
# перед первым элементом списка
# 3-й аргумент означает повторный проход по списку в обратном направлении,
# уменьшая счётчик i на 1
for i in range(n, -1, -1):
heapify(num, n, i)
# Перемещаем корень Max Heap в конец списка
for i in range(n – 1, 0, -1):
num[i], num[0] = num[0], num[i]
heapify(num, i, 0)
def merge(left_list, right_list):
sorted_list = []
left_list_index = right_list_index = 0
# Длина списков часто используется, поэтому создадим переменные для удобства
left_list_length, right_list_length = len(left_list), len(right_list)
for _ in range(left_list_length + right_list_length):
if left_list_index < left_list_length and right_list_index < right_list_length:
# Сравниваем первые элементы в начале каждого списка
# Если первый элемент левого подсписка меньше, добавляем его
# в отсортированный массив
if left_list[left_list_index] <= right_list[right_list_index]:
sorted_list.append(left_list[left_list_index])
left_list_index += 1
# Если первый элемент правого подсписка меньше, добавляем его
# в отсортированный массив
else:
sorted_list.append(right_list[right_list_index])
right_list_index += 1
# Если достигнут конец левого списка, элементы правого списка
# добавляем в конец результирующего списка
elif left_list_index == left_list_length:
sorted_list.append(right_list[right_list_index])
right_list_index += 1
# Если достигнут конец правого списка, элементы левого списка
# добавляем в отсортированный массив
elif right_list_index == right_list_length:
sorted_list.append(left_list[left_list_index])
left_list_index += 1
return sorted_list
def merge_sort(num):
# Возвращаем список, если он состоит из одного элемента
if len(num) <= 1:
return num
# Для того чтобы найти середину списка, используем деление без остатка
# Индексы должны быть integer
mid = len(num) // 2
# Сортируем и объединяем подсписки
left_list = merge_sort(num[:mid])
right_list = merge_sort(num[mid:])
# Объединяем отсортированные списки в результирующий
return merge(left_list, right_list)
#—
def partition(num, low, high):
# Выбираем средний элемент в качестве опорного
# Также возможен выбор первого, последнего
# или произвольного элементов в качестве опорного
pivot = num[(low + high) // 2]
i = low – 1
j = high + 1
while True:
i += 1
while num[i] < pivot:
i += 1
j -= 1
while num[j] > pivot:
j -= 1
if i >= j:
return j
# Если элемент с индексом i (слева от опорного) больше, чем
# элемент с индексом j (справа от опорного), меняем их местами
num[i], num[j] = num[j], num[i]
def quick_sort(num):
# Создадим вспомогательную функцию, которая вызывается рекурсивно
def _quick_sort(items, low, high):
if low < high:
# This is the index after the pivot, where our lists are split
split_index = partition(items, low, high)
_quick_sort(items, low, split_index)
_quick_sort(items, split_index + 1, high)
_quick_sort(num, 0, len(num) – 1)
#–
def summa (num, z):
for i in range(z):
list.pop(0)
list.pop()
sum=0
for i in range(len(num) – 1):
sum +=list[i]
sum /= (len(list)-1)
return sum
# Смотрим что вышло
t1 = utime.ticks_us()
bubble_sort(list)
#print(list)
rez=summa (list, 3)
#print(list)
t2 = utime.ticks_us()
temp = (t2 – t1)
#print(‘Sum_bublle=%f’ % rez)
#print(‘T_bublle=%uus’ % temp)
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
t1 = utime.ticks_us()
selection_sort(list)
rez1=summa (list, 3)
t2 = utime.ticks_us()
temp1 = (t2 – t1)
#print(‘Sum_selection=%f’ % rez1)
#print(‘T_selection=%uus’ % temp1)
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
t1 = utime.ticks_us()
insertion_sort(list)
rez2=summa (list, 3)
t2 = utime.ticks_us()
temp2 = (t2 – t1)
#print(‘Sum_selection=%f’ % rez2)
#print(‘T_selection=%uus’ % temp2)
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
t1 = utime.ticks_us()
heap_sort(list)
rez3=summa (list, 3)
t2 = utime.ticks_us()
temp3 = (t2 – t1)
#print(‘Sum_heap=%f’ % rez3)
#print(‘T_heap=%uus’ % temp3)
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
t1 = utime.ticks_us()
list=merge_sort(list)
rez4=summa (list, 3)
t2 = utime.ticks_us()
temp4 = (t2 – t1)
#print(‘Sum_merge=%f’ % rez4)
#print(‘T_merge=%uus’ % temp4)
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
t1 = utime.ticks_us()
quick_sort(list)
rez5=summa (list, 3)
t2 = utime.ticks_us()
temp5 = (t2 – t1)
#print(‘Sum_quick=%f’ % rez5)
#print(‘T_quick=%uus’ % temp5)
print(‘T_bublle=%uus T_selection=%uus T_insertion=%uus T_heap=%uus T_merge=%uus T_quick=%uus’ % (temp, temp1, temp2, temp3, temp4, temp5))
print(‘Sum_bublle=%f Sum_selection=%f Sum_insertion=%f Sum_heap=%f Sum_merge=%f Sum_quick=%f’ % (rez, rez1, rez2, rez3, rez4, rez5))
import utime
import machine, time
def summa (num, z):
for i in range(z):
list.pop(0)
list.pop()
sum=0
for i in range(len(num) — 1):
sum +=list[i]
sum /= (len(list) — 1)
return sum
def bubble_sort(num):
# Устанавливаем sw в True, для запуска цикл минимум один раз
sw = True
while sw:
sw = False
for i in range(len(num) — 1):
if num[i] > num[i + 1]:
# Меняем элементы
num[i], num[i + 1] = num[i + 1], num[i]
# Устанавливаем sw в True для следующей итерации
sw = True
def selection_sort(num):
# Значение i соответствует кол-ву отсортированных значений
for i in range(len(num)):
# Исходно считаем наименьшим первый элемент
index = i
# Этот цикл перебирает несортированные элементы
for j in range(i + 1, len(num)):
if num[j] < num[index]:
index = j
# Самый маленький элемент меняем с первым в списке
num[i], num[index] = num[index], num[i]
def insertion_sort(num):
# Сортировку начинаем со второго элемента, т.к. считается, что первый элемент уже отсортирован
for i in range(1, len(num)):
insert = num[i]
# Сохраняем ссылку на индекс предыдущего элемента
j = i — 1
# Элементы отсортированного сегмента перемещаем вперёд, если они больше
# элемента для вставки
while j >= 0 and num[j] > insert:
num[j + 1] = num[j]
j -= 1
# Вставляем элемент
num[j + 1] = insert
def heapify(num, heap_size, root_index):
# Индекс наибольшего элемента считаем корневым индексом
largest = root_index
left_child = (2 * root_index) + 1
right_child = (2 * root_index) + 2
# Если левый потомок корня — допустимый индекс, а элемент больше,
# чем текущий наибольший, обновляем наибольший элемент
if left_child < heap_size and num[left_child] > num[largest]:
largest = left_child
# То же самое для правого потомка корня
if right_child < heap_size and num[right_child] > num[largest]:
largest = right_child
# Если наибольший элемент больше не корневой, они меняются местами
if largest != root_index:
num[root_index], num[largest] = num[largest], num[root_index]
# Heapify the new root element to ensure it’s the largest
heapify(num, heap_size, largest)
def heap_sort(num):
n = len(num)
# Создаём Max Heap из списка
# Второй аргумент означает остановку алгоритма перед элементом -1, т.е.
# перед первым элементом списка
# 3-й аргумент означает повторный проход по списку в обратном направлении,
# уменьшая счётчик i на 1
for i in range(n, -1, -1):
heapify(num, n, i)
# Перемещаем корень Max Heap в конец списка
for i in range(n — 1, 0, -1):
num[i], num[0] = num[0], num[i]
heapify(num, i, 0)
def merge(left_list, right_list):
sorted_list = []
left_list_index = right_list_index = 0
# Длина списков часто используется, поэтому создадим переменные для удобства
left_list_length, right_list_length = len(left_list), len(right_list)
for _ in range(left_list_length + right_list_length):
if left_list_index < left_list_length and right_list_index < right_list_length:
# Сравниваем первые элементы в начале каждого списка
# Если первый элемент левого подсписка меньше, добавляем его
# в отсортированный массив
if left_list[left_list_index] <= right_list[right_list_index]:
sorted_list.append(left_list[left_list_index])
left_list_index += 1
# Если первый элемент правого подсписка меньше, добавляем его
# в отсортированный массив
else:
sorted_list.append(right_list[right_list_index])
right_list_index += 1
# Если достигнут конец левого списка, элементы правого списка
# добавляем в конец результирующего списка
elif left_list_index == left_list_length:
sorted_list.append(right_list[right_list_index])
right_list_index += 1
# Если достигнут конец правого списка, элементы левого списка
# добавляем в отсортированный массив
elif right_list_index == right_list_length:
sorted_list.append(left_list[left_list_index])
left_list_index += 1
return sorted_list
def merge_sort(num):
# Возвращаем список, если он состоит из одного элемента
if len(num) <= 1:
return num
# Для того чтобы найти середину списка, используем деление без остатка
# Индексы должны быть integer
mid = len(num) // 2
# Сортируем и объединяем подсписки
left_list = merge_sort(num[:mid])
right_list = merge_sort(num[mid:])
# Объединяем отсортированные списки в результирующий
return merge(left_list, right_list)
def partition(numbers, low, high):
# Выбираем средний элемент в качестве опорного
# Также возможен выбор первого, последнего
# или произвольного элементов в качестве опорного
pivot = numbers[high]
item = low — 1
for i in range(low, high):
if numbers[i] <= pivot:
item = item + 1
(numbers[item], numbers[i]) = (numbers[i], numbers[item])
(numbers[item + 1], numbers[high]) = (numbers[high], numbers[item + 1])
return item + 1
def quick_sort(numbers, low, high):
if low < high:
pivot = partition(numbers, low, high)
quick_sort(numbers, low, pivot — 1)
quick_sort(numbers, pivot + 1, high)
# Смотрим что вышло
time.sleep_ms(100)
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
t1 = utime.ticks_us()
bubble_sort(list)
rez=summa (list, 3)
t2 = utime.ticks_us()
temp = (t2 — t1)
time.sleep_ms(100)
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
t1 = utime.ticks_us()
selection_sort(list)
rez1=summa (list, 3)
t2 = utime.ticks_us()
temp1 = (t2 — t1)
time.sleep_ms(100)
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
t1 = utime.ticks_us()
insertion_sort(list)
rez2=summa (list, 3)
t2 = utime.ticks_us()
temp2 = (t2 — t1)
time.sleep_ms(100)
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
t1 = utime.ticks_us()
heap_sort(list)
rez3=summa (list, 3)
t2 = utime.ticks_us()
temp3 = (t2 — t1)
time.sleep_ms(100)
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
t1 = utime.ticks_us()
list=merge_sort(list)
rez4=summa (list, 3)
t2 = utime.ticks_us()
temp4 = (t2 — t1)
time.sleep_ms(100)
list = [10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.97,10.0, 10.2, 10.1, 11.0, 10.3, 9.99, 9.98, 10.1, 10.2, 9.87]
t1 = utime.ticks_us()
quick_sort(list,0, len(list)-1)
rez5=summa (list, 3)
t2 = utime.ticks_us()
temp5 = (t2 — t1)
time.sleep_ms(100)
print(‘T_bublle=%uus; T_selection=%uus; T_insertion=%uus; T_heap=%uus; T_merge=%uus; T_quick=%uus’ % (temp, temp1, temp2, temp3, temp4, temp5))
time.sleep_ms(100)
print(‘Sum_bublle=%f; Sum_selection=%f; Sum_insertion=%f; Sum_heap=%f; Sum_merge=%f; Sum_quick=%f’ % (rez, rez1, rez2, rez3, rez4, rez5))