在 Raspberry Pi 上使用 Python 从传感器存储数据的最有效方法
Posted
技术标签:
【中文标题】在 Raspberry Pi 上使用 Python 从传感器存储数据的最有效方法【英文标题】:The most efficient way to store data from sensor using Python on Raspberry Pi 【发布时间】:2020-02-21 11:57:03 【问题描述】:我正在使用 SPI 从 IMU LSM9DS1 读取数据。我想将数据存储到文件中。我尝试使用with open as file
和.write
保存为txt 文件。速度为0.002s。
while flag:
file_path_g = '/home/pi/Desktop/LSM9DS1/gyro.txt'
with open(file_path_g, 'a') as out_file_g:
dps = dev.get_gyro()
out_file_g.write(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'))
out_file_g.write(" 0:0.3f, 1:0.3f, 2:0.3f\n".format(dps[0], dps[1], dps[2]))
file_path_a = '/home/pi/Desktop/LSM9DS1/accel.txt'
with open(file_path_a, 'a') as out_file_a:
acc = dev.get_acc()
out_file_a.write(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'))
out_file_g.write(" 0:0.3f, 1:0.3f, 2:0.3f\n".format(acc[0], acc[1], acc[2]))
# time.sleep(0.2)
print("interrupt occured")
dev.close()
我还尝试使用 pandas 将数据保存为 .csv 文件。速度比第一个慢。
while flag:
t = time.time()
acc = dev.get_acc()
dps = dev.get_gyro()
ax = acc[0]
ay = acc[1]
az = acc[2]
gx = dps[0]
gy = dps[1]
gz = dps[2]
result = pd.DataFrame('time':t, 'ax':ax,'ay':ay,'az':az,'gx':gx,'gy':gy,'gz':gz,index=[0])
result.to_csv('/home/pi/Desktop/LSM9DS1/result.csv', mode='a', float_format='%.6f',
header=False, index=0)
dev.close()
如何提高阅读速度?
我更新了路径之外的代码。
file_path = '/home/pi/Desktop/LSM9DS1/result.txt'
while flag:
with open(file_path, 'a') as out_file:
acc = dev.get_acc()
dps = dev.get_gyro()
out_file.write(datetime.datetime.now().strftime('%S.%f'))
out_file.write(" 0:0.3f, 1:0.3f, 2:0.3f".format(acc[0], acc[1], acc[2]))
out_file.write(" 0:0.3f, 1:0.3f, 2:0.3f\n".format(dps[0], dps[1], dps[2]))
这是另一种方式
while flag:
t = time.time()
acc = dev.get_acc()
dps = dev.get_gyro()
arr = [t, acc[0], acc[1], acc[2], dps[0], dps[1],dps[2]],
np_data = np.array(arr)
result = pd.DataFrame(np_data,index=[0])
result.to_csv('/home/pi/Desktop/LSM9DS1/result.csv', mode='a', float_format='%.6f', header=False, index=0)
感谢马克的回答。我照他说的做了,改代码如下。
samples=[]
for i in range(100000):
t = time.time()
acc = dev.get_acc()
dps = dev.get_gyro()
# Append a tuple (containing time, acc and dps) onto sample list
samples.append((t, acc, dps))
name = ['t','acc','dps']
f = pd.DataFrame(columns=name,data=samples)
f.to_csv('/home/pi/Desktop/LSM9DS1/result.csv', mode='a', float_format='%.6f', header=False, index=0)
print('done')
我计算了时间空间(前600个数据),平均值为0.000265,比以前快了很多,几乎是以前的10倍。
【问题讨论】:
评论不用于扩展讨论;这个对话是moved to chat。 我的回答解决了您的问题吗?如果是这样,请考虑接受它作为您的答案 - 通过单击计票旁边的空心对勾/复选标记。如果没有,请说出什么不起作用,以便我或其他人可以进一步为您提供帮助。谢谢。 meta.stackexchange.com/questions/5234/… 【参考方案1】:正如我在 cmets 中所说的:“答案非常不同,具体取决于您要做什么!如果陀螺仪在无人机上,并且您将数据发送到电脑控制方向,你需要以最小的延迟将最新的读数送到电脑上——这不需要存储,4秒前的数据是没有用的。如果你运行一个实验4个小时,然后再分析结果,您可能希望以最大速率读取陀螺仪,将其全部存储在本地并在最后传输 - 这需要更多存储空间。”
存储大量样本最快的地方是在 RAM 中的列表中:
samples=[]
while flag:
t = time.time()
acc = dev.get_acc()
dps = dev.get_gyro()
# Append a tuple (containing time, acc and dps) onto sample list
samples.append((t, acc, dps))
基准测试
在我的桌面上在 IPython 中运行,每秒可以存储 280 万个元组,每个元组包含时间和 2 个列表,每个列表包含 3 个元素:
In [92]: %%timeit
...:
...: samples=[]
...: for i in range(2800000):
...: t = time.time()
...: acc = [1,2,3]
...: dps = [4,5,6]
...: # Append a tuple (containing time, acc and dps) onto sample list
...: samples.append((t, acc, dps))
1.05 s ± 7.13 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
【讨论】:
你好马克,我想知道将数据保存到文件的速度是否有影响。当保存速度比读取慢时,我们会不会丢失一些数据? 我展示的代码没有写入文件。它将样本存储在内存 (RAM) 中的 Python 列表中。 如果我想将“样本”存储到文件中该怎么办,另一个答案说最好保存为二进制格式的文件。我尝试使用“struct”,TypeError 说“需要一个类似字节的对象,而不是 'tuple'” 我建议您在实验期间将数据存储在内存中,因为您说您希望尽可能快地进行,并且内存比磁盘快 1000 倍。然后,我建议您在实验结束时将数据写入磁盘,无论需要 12 秒还是 15 秒都没有关系。所以磁盘上的格式并不重要。 非常感谢!我试图将数据保存为 csv 文件,但第二列和第三列中的值也是一个列表。如何在 MATLAB 中读取数据。【参考方案2】:一些可以提高速度的想法,您可以尝试一下:
-
使用二进制格式而不是文本 - 写入二进制时间(参见:
Write and read Datetime to binary format in Python)
并写二进制浮点数。您可以稍后离线处理它们。
并行调用 get_acc 和 get_gyro
在内存中存储一些测量值并写入整个缓冲区
一次调用而不是多次调用 write
有单独的线程用于写入和单独的线程用于获取
测量
用 C 重写
【讨论】:
感谢您的建议,我先尝试使用二进制格式,之后我可以将其更改为浮动。以上是关于在 Raspberry Pi 上使用 Python 从传感器存储数据的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章
在Raspberry Pi上安装mitmproxy时出现python问题
在 Raspberry PI 上使用 Python 和 OpenCV 进行图像处理 [关闭]
如何使用 Python 在 Raspberry Pi 上杀死 omxplayer 播放器