簡體   English   中英

在 Raspberry Pi 上使用 Python 存儲來自傳感器的數據的最有效方法

[英]The most efficient way to store data from sensor using Python on Raspberry Pi

我正在使用 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倍。

一些可以提高速度的想法,您可以嘗試:

  1. 使用二進制格式而不是文本 - 寫入二進制時間(請參閱: 在 Python 中將日期時間寫入和讀取為二進制格式)並寫入二進制浮點數。 您可以稍后離線處理它們。
  2. 並行調用 get_acc 和 get_gyro
  3. 在內存中存儲一​​些測量值並一次寫入它們的整個緩沖區,而不是多次調用 write
  4. 有單獨的線程用於寫入和單獨的線程用於獲取測量
  5. 用 C 重寫

正如我在評論中說:“答案是取決於你正在嘗試做的完全不同。如果陀螺儀是一個懶惰,你將數據發送到一台PC來控制方向,你需要獲得最新的閱讀!以最小的延遲傳輸到 PC - 這不需要存儲,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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM