使用元數據在 SQLite 中儲存許多 pandas DataFrame
我需要一些幫助來設計數據庫。我的目標是以可搜尋的方式持久儲存許多Pandas數據幀,從我讀到的內容來看,SQLite 非常適合這項任務。
每個 DataFrame 包含大約一百萬行粒子運動數據,如下所示:
z y x frame particle 0 49.724138 45.642857 813.035714 0 0 3789 14.345679 2820.537500 4245.162500 0 1 3788 10.692308 2819.210526 1646.842105 0 2 3787 34.100000 2817.700000 1375.300000 0 3 3786 8.244898 2819.729167 1047.375000 0 4
使用 sqlalchemy,我已經可以將每個 DataFrame 作為一個表儲存在一個新的數據庫中:
from sqlalchemy import create_engine import pandas as pd engine = create_engine("sqlite:////mnt/storage/test.db") exp1.to_sql("exp1", engine, if_exists="replace") exp2.to_sql("exp2", engine, if_exists="replace") exp3.to_sql("exp3", engine, if_exists="replace")
但這太基礎了。如何將每個 DataFrame/experiment 與幾個元數據欄位(例如)一起儲存
Name
,Date
以便以後可以返回由某個人或在特定日期進行的所有實驗?隨著時間的推移,我會添加更多的列。假設每個 DataFrame/experiment 都有一個 column
velocity
,我如何檢索平均溫度值低於或高於任意門檻值的所有實驗?
您已經創建了 3 個單獨的表(以及 2 個,等待明顯的拼寫錯誤?)。如果你想統一數據,你可能不應該強行覆蓋目標表
if_exists="replace"
- 替換:在插入新值之前刪除表。
- append:向現有表中插入新值。
假設您的名稱相似的文件具有相同的架構,您可以按如下方式編輯最後 3 行。
exp1.to_sql("exp", engine, if_exists="append") exp2.to_sql("exp", engine, if_exists="append") exp3.to_sql("exp", engine, if_exists="append")
這會將所有三個數據集插入到一個名為
exp
而不是 3 個單獨的表的單個表中。如果每個 csv 不是從其自身內部的其他 csv 中唯一標識的 - 例如,如果
exp1.csv
看起來像這樣……Name,Date,Temperature Peter,2020-01-01,50 Paul,2020-01-01,55 Mary,2020-01-01,53 Jane,2020-01-01,49
…然後您可以根據數據框中的需要將實驗標識符附加到每個數據集。例如通過…
>>> exp1['ExpName'] = 'exp1' >>> exp1 Name Date Temperature ExpName 0 Peter 2020-01-01 50 exp1 1 Paul 2020-01-01 55 exp1 2 Mary 2020-01-01 53 exp1 3 Jane 2020-01-01 49 exp1 >>>
…這將允許您在可能針對您的數據庫執行的任何後續 SQL 中通過實驗進行分組。
…我如何檢索平均溫度值低於或高於任意門檻值的所有實驗?
…好吧,給定任意額外的兩個數據集…
➜ /tmp cat exp2.csv Name,Date,Temperature Peter,2020-01-02,51 Paul,2020-01-02,56 Mary,2020-01-02,54 Jane,2020-01-02,50 ➜ /tmp cat exp3.csv Name,Date,Temperature Peter,2020-01-02,52 Paul,2020-01-02,57 Mary,2020-01-02,55 Jane,2020-01-02,51 ➜ /tmp
…您同樣將
expN
標識符附加到數據框中,然後您將執行以下 SQL來檢索平均溫度低於 53 的實驗SELECT ExpName, AVG(Temperature) FROM exp GROUP BY ExpName HAVING AVG(Temperature) < 53;
我將留給您根據需要插入 SQLAlchemy :)