在python中滚动数组

Posted

技术标签:

【中文标题】在python中滚动数组【英文标题】:Scrolling an array in python 【发布时间】:2019-04-17 15:18:28 【问题描述】:

我目前正在使用 pyserial 和 pyqtgraph 编写一个 python 脚本,该脚本可以绘制通过串行端口从加速度计传入的数据。我将此数据附加到一个 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)

这样我避免了一个不断增长的数组,也避免了通过向左移动元素来复制值。然而,我的情节不一致并且偶尔会滞后(当我移动传感器时,情节会在几秒钟后做出反应)。这是因为我滚动数据效率低吗?

【问题讨论】:

【参考方案1】:

要进行 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]
....

【讨论】:

【参考方案2】:

以下是此类 FIFO 功能的一个很好的参考:Queues in Python

从那个链接总结:

考虑使用collections.deque 处理此行为,因为列表很慢。

【讨论】:

我想到了 deque 但 setData 函数只需要 numpy 数组 你可以把deque对象转成一个列表(xdata1 = np.array(list(your_queue,dtype='int')),不知道对效率有什么影响。 忘记了,但你明白了。

以上是关于在python中滚动数组的主要内容,如果未能解决你的问题,请参考以下文章

在 2D numpy 数组的每个滚动窗口中获取最大值

滚动数组

iphone SDK:不能在图像数组中对角滚动?

如何在选择新数组被播放到该滚动视图时,如何删除将放置到滚动视图中的UIBUtonons?

如何从数组中过滤数据并使用角度js应用无限滚动?

01背包+滚动数组