我对 Python 比较陌生,正在寻找用于旋转大型多维数组的最佳优化代码。在下面的代码中,我有一个 16X600000 32 位浮点多维数组,根据计时器,旋转我的四核 acer windows 8 平板电脑上的内容大约需要 30 毫秒。如果可以减少旋转阵列所需的时间,我正在考虑使用一些 Cython 例程或类似的东西。
最终,代码将用于存储基于 VisPy 包的高速数据绘图图的 y 轴值,并将 32 位浮点数组传递给 OpenGL 例程。如果可能的话,我希望达到不到 1 毫秒。
任何评论、建议或示例代码将不胜感激。
import sys, timeit
from threading import Thread
from PyQt4 import QtGui
import numpy as np
m = 16 # Number of signals.
n = 600000 # Number of samples per signal.
y = 0.0 * np.random.randn(m, n).astype(np.float32)
Running = False
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.button = QtGui.QPushButton('Start', self)
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.button)
def handleButton(self):
global Running, thread, thrTest
if Running == True:
Running = False
self.button.setText('Start')
thrTest.isRunning = False
print ('stop')
else:
Running = True
self.button.setText('Stop')
thrTest = testThread()
thread = Thread(target=thrTest.run, daemon=True )
thread.start()
print ("Start")
class testThread(Thread):
def __init__(self):
self.isRunning = True
def run(self):
print('Test: Thread Started')
while self.isRunning == True:
start_time = timeit.default_timer()
y[:, :-1] = y[:, 1:]
elapsed = timeit.default_timer() - start_time
print ('Time (s)= ' + str(elapsed))
print('Test: Closed Thread')
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
更新
我想我到底要做什么有些困惑,所以我会尝试更好地解释一下。
最终目标是拥有一个快速的实时数据记录设备,该设备在表示信号值的图表上画线。将有多个通道和至少 1ms 的采样率和尽可能多的记录时间。我从这个 VisPy 示例开始。示例中将新数据写入数组并将其发送到 OpenGL 的On_Timer
代码位于底部附近的函数中。我稍微修改了这段代码以将 OpenGL 画布集成到 Qt gui 中,并添加了一些代码以通过以太网套接字从 Arduino Mega 获取数据。
目前,我可以生成 16 条线的实时图表,采样率约为 1 毫秒,帧率约为 30 赫兹,记录时间约为 14 秒。如果我尝试再增加通道数或记录长度,程序将停止工作,因为它无法跟上 1ms 通过以太网端口进入的数据流。
我能找到的最大罪魁祸首是使用y[:, :-1] = y[:, 1:]
例程完成数据缓冲区移位所需的时间。最初我提交了这个函数正在计时的基准代码,希望有人知道以更有效的方式做同样事情的方法。这一行的目的是将整个数组向左移动一个索引,然后在我的下一行代码中,我将新数据写入右侧的第一个槽。
您可以在下面看到我修改后的图形更新例程。首先它从队列中取出新数据并解包到一个临时数组中,然后移动主缓冲区数组的内容,最后将新数据复制到主数组的最后一个槽中。一旦队列为空,它就会调用更新函数,以便 OpenGL 更新显示。
def on_timer(self, event):
"""Add some data at the end of each signal (real-time signals)."""
k=1
s = struct.Struct('>16H')
AdrArray = 0.0 * np.random.randn(16,1).astype(np.float32)
if not q.qsize() == 0:
while q.qsize() > 0:
print (q.qsize())
print ('iin ' + str(datetime.datetime.now()))
AdrArray[:,0]= s.unpack_from(q.get(), offset=4)
y[:, :-1] = y[:, 1:]
y[:, -1:] = .002*AdrArray
print ('out ' + str(datetime.datetime.now()))
self.program['a_position'].set_data(y.ravel().astype(np.float32))
self.update()