Прокрутка массива в питоне - PullRequest
0 голосов
/ 14 ноября 2018

В настоящее время я пишу скрипт на python с pyserial и pyqtgraph, который отображает данные, поступающие с акселерометра через последовательный порт.Я добавляю эти данные в массив int и использую его для обновления графика.На данный момент ширина моего графика составляет 500 (я отображаю только самые последние 500 элементов), и я «прокручиваю» или «прокручиваю», добавляя элемент в конец и выталкивая с самого начала.

data1 = [0] * 500

def update():
  global curve1, data1, x, ser
  if(ser != None): ## serial object. defined via a QPushButton event
    line = ser.readline()
    csv = line.decode().split(',')
    if len(csv) == 2:       
      data1.append(int(csv[1]))
      data1.pop(0)
      xdata1 = np.array(data1[-500:], dtype='int')
      curve1.setData(xdata1)
      x += 1
      curve1.setPos(x, 0)
      app.processEvents()

Этот метод обновления вызывается объектом QtTimer для обновления окна графика

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)

Таким образом, я избегаю массива, который продолжает расти, а также избегаю копирования значений путем смещения элементов влево.Мой график, однако, противоречив и иногда отстает (когда я перемещаю датчик, график реагирует несколько секунд спустя).Это из-за того, что я перевожу свои данные неэффективно?

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Чтобы выполнить процедуру обновления O (1), вы можете сделать это самостоятельно с буфером с двумя массивами:

size=4
buffersize=2*size
buffer=np.zeros(buffersize+1,int) # one more room  for keep trace on beginning of buffer.
sensor=iter(range(1,10**5)) # emulation

def update():
    i=buffer[buffersize] # to avoid global variable i
    buffer[i]=buffer[i+size]=next(sensor) # double copy.
    buffer[buffersize]=i=(i+1)%size
    print(i,buffer[:buffersize],buffer[i:i+size])
    # In real life : curve1.SetData(buffer[i:i+size])

Поскольку buffer[i:i+size] - это просто представление, обновление не займет времени. curve1.

Прогон:

>>> for k in range(6): update()

1 [1 0 0 0 1 0 0 0] [0 0 0 1]
2 [1 2 0 0 1 2 0 0] [0 0 1 2]
3 [1 2 3 0 1 2 3 0] [0 1 2 3]
0 [1 2 3 4 1 2 3 4] [1 2 3 4]
1 [5 2 3 4 5 2 3 4] [2 3 4 5]
2 [5 6 3 4 5 6 3 4] [3 4 5 6]
....
0 голосов
/ 14 ноября 2018

Вот хороший справочник для такого рода функций FIFO: Очереди в Python

Подводя итог по этой ссылке:

Рассмотрите возможность использования collections.deque для этого поведения, так как списки медленные.

...