一、概述
在進行探索性數據分析時 (例如,在使用pandas檢查COVID-19數據時),通常會將CSV,XML或JSON等文件加載到 pandas DataFrame中。然后,您可能需要對DataFrame中的數據進行一些處理,並希望將其存儲在關系數據庫等更持久的位置。
本教程介紹了如何從CSV文件加載pandas DataFrame,如何從完整數據集中提取一些數據,然后使用SQLAlchemy將數據子集保存到SQLite數據庫 。
二、配置開發環境
確保已安裝Python 3。截至目前, Python 3.8.2是Python的最新版本。
在本教程中,我們還將使用:
- pandas(項目主頁 和源代碼),本教程中的版本1.1.5
- SQLAlchemy (項目主頁和 源代碼),本教程的1.3.20
- SQLite(項目首頁 和源代碼),Python 包含一個連接器,作為Python標准庫的一部分
使用以下命令將上述代碼庫安裝到新的 Python虛擬環境中:
pip3 install pandas sqlalchemy
現在,我們的開發環境已准備好下載示例COVID-19數據集,將其加載到pandas DataFrame中,對其進行一些分析,然后保存到SQLite數據庫中。
三、獲取COVID-19數據
在您的網絡瀏覽器中, 下載關於當今全球COVID-19病例地理分布頁面的數據下載。它看起來應類似於以下屏幕截圖。

應該有一個以CSV格式下載數據的鏈接,但是該組織在過去幾周內多次更改了頁面布局,這使得很難找到Excel(XLSX)以外的格式。如果您在獲取CSV版本時遇到問題,只需從GitHub下載此版本即可,該版本 與2020年12月10日下載的副本掛鈎。
四、將CSV導入pandas
原始數據位於CSV文件中,我們需要通過pandas DataFrame將其加載到內存中。
REPL准備執行代碼,但是我們首先需要導入pandas庫,以便可以使用它。
from pandas import read_csv df = read_csv("data.csv", encoding="ISO-8859-1")
現在將數據加載到df作為pandas DataFrame 類實例的變量中 。
count在此DataFrame上運行該函數時,我們會發現它具有61048行。
from pandas import read_csv df = read_csv("data.csv", encoding="ISO-8859-1") print(df.count())
執行輸出:
dateRep 61048 day 61048 month 61048 year 61048 cases 61048 deaths 61048 countriesAndTerritories 61048 geoId 60777 countryterritoryCode 60929 popData2019 60929 continentExp 61048 Cumulative_number_for_14_days_of_COVID-19_cases_per_100000 58173 dtype: int64
接下來,我們將采用這組61048行數據,並僅切出與美國有關的行。
從原始數據幀創建新的數據幀
我們可以使用pandas函數將單個國家/地區的所有數據行匹配countriesAndTerritories到與所選國家/地區匹配的列。
from pandas import read_csv df = read_csv("data.csv", encoding="ISO-8859-1") # print(df.count()) save_df = df[df['countriesAndTerritories']=="United_States_of_America"] print(save_df)
該save_df變量包含數據的較小的子集。您可以通過自己打印來找出其中的內容:
您應該看到類似以下輸出的內容:
dateRep ... Cumulative_number_for_14_days_of_COVID-19_cases_per_100000 58197 10/12/2020 ... 794.356027 58198 09/12/2020 ... 784.195114 58199 08/12/2020 ... 769.896719 58200 07/12/2020 ... 762.794473 58201 06/12/2020 ... 757.944062 ... ... ... ... 58538 04/01/2020 ... NaN 58539 03/01/2020 ... NaN 58540 02/01/2020 ... NaN 58541 01/01/2020 ... NaN 58542 31/12/2019 ... NaN [346 rows x 12 columns]
原始61048行中有346行數據。讓我們繼續將此子集保存到SQLite關系數據庫中。
將DataFrame保存到SQLite
我們將使用SQLAlchemy創建與新SQLite數據庫的連接,在此示例中,該數據庫將存儲在名為的文件中save_pandas.db。當然,您可以使用所需的任何名稱在任何位置保存文件,而不僅是在執行Python REPL的目錄中保存。
首先create_engine從sqlalchemy 庫中導入函數。
使用導入的create_engine函數創建連接,然后connect在其上調用方法。
from pandas import read_csv df = read_csv("data.csv", encoding="ISO-8859-1") # print(df.count()) save_df = df[df['countriesAndTerritories']=="United_States_of_America"] # print(save_df) from sqlalchemy import create_engine engine = create_engine('sqlite:///save_pandas.db', echo=True) sqlite_connection = engine.connect()
我們設置echo=True為查看來自數據庫連接的所有輸出。連接成功后,您將看到類似於以下的輸出:
2020-12-11 16:30:21,542 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 2020-12-11 16:30:21,543 INFO sqlalchemy.engine.base.Engine () 2020-12-11 16:30:21,544 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 2020-12-11 16:30:21,545 INFO sqlalchemy.engine.base.Engine ()
使用您要創建的表名的字符串設置變量名。然后to_sql 在save_df對象上調用該方法時使用該變量,這是我們的pandas DataFrame,它是原始數據集的子集,從原始7320中篩選出89行。
請注意,在這種情況下,如果表已經存在於數據庫中,我們將失敗。您可以在該程序的更強大的版本中更改if_exists為replace 或append添加自己的異常處理。查看 pandas.DataFrame.to_sql 文檔,以獲取有關您的選項的詳細信息。
# !/usr/bin/python3 # -*- coding: utf-8 -*- from pandas import read_csv df = read_csv("data.csv", encoding="ISO-8859-1") # print(df.count()) save_df = df[df['countriesAndTerritories']=="United_States_of_America"] # print(save_df) from sqlalchemy import create_engine engine = create_engine('sqlite:///save_pandas.db', echo=True) sqlite_connection = engine.connect() sqlite_table = "Covid19" save_df.to_sql(sqlite_table, sqlite_connection, if_exists='fail') sqlite_connection.close()
執行輸出:
2020-12-11 16:31:11,484 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 2020-12-11 16:31:11,484 INFO sqlalchemy.engine.base.Engine () 2020-12-11 16:31:11,485 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 2020-12-11 16:31:11,485 INFO sqlalchemy.engine.base.Engine () 2020-12-11 16:31:11,489 INFO sqlalchemy.engine.base.Engine PRAGMA main.table_info("Covid19") 2020-12-11 16:31:11,489 INFO sqlalchemy.engine.base.Engine () 2020-12-11 16:31:11,490 INFO sqlalchemy.engine.base.Engine PRAGMA temp.table_info("Covid19") 2020-12-11 16:31:11,490 INFO sqlalchemy.engine.base.Engine () 2020-12-11 16:31:11,492 INFO sqlalchemy.engine.base.Engine CREATE TABLE "Covid19" ( "index" BIGINT, "dateRep" TEXT, day BIGINT, month BIGINT, year BIGINT, cases BIGINT, deaths BIGINT, "countriesAndTerritories" TEXT, "geoId" TEXT, "countryterritoryCode" TEXT, "popData2019" FLOAT, "continentExp" TEXT, "Cumulative_number_for_14_days_of_COVID-19_cases_per_100000" FLOAT ) 2020-12-11 16:31:11,492 INFO sqlalchemy.engine.base.Engine () 2020-12-11 16:31:11,506 INFO sqlalchemy.engine.base.Engine COMMIT 2020-12-11 16:31:11,507 INFO sqlalchemy.engine.base.Engine CREATE INDEX "ix_Covid19_index" ON "Covid19" ("index") 2020-12-11 16:31:11,507 INFO sqlalchemy.engine.base.Engine () 2020-12-11 16:31:11,516 INFO sqlalchemy.engine.base.Engine COMMIT 2020-12-11 16:31:11,519 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 2020-12-11 16:31:11,524 INFO sqlalchemy.engine.base.Engine INSERT INTO "Covid19" ("index", "dateRep", day, month, year, cases, deaths, "countriesAndTerritories", "geoId", "countryterritoryCode", "popData2019", "continentExp", "Cumulative_number_for_14_days_of_COVID-19_cases_per_100000") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 2020-12-11 16:31:11,525 INFO sqlalchemy.engine.base.Engine ((58197, '10/12/2020', 10, 12, 2020, 220025, 3124, 'United_States_of_America', 'US', 'USA', 329064917.0, 'America', 794.35602672), (58198, '09/12/2020', 9, 12, 2020, 217344, 2564, 'United_States_of_America', 'US', 'USA', 329064917.0, 'America', 784.1951137), (58199, '08/12/2020', 8, 12, 2020, 197334, 1433, 'United_States_of_America', 'US', 'USA', 329064917.0, 'America', 769.89671919), (58200, '07/12/2020', 7, 12, 2020, 173432, 1111, 'United_States_of_America', 'US', 'USA', 329064917.0, 'America', 762.79447316), (58201, '06/12/2020', 6, 12, 2020, 211933, 2203, 'United_States_of_America', 'US', 'USA', 329064917.0, 'America', 757.94406245), (58202, '05/12/2020', 5, 12, 2020, 231930, 2680, 'United_States_of_America', 'US', 'USA', 329064917.0, 'America', 746.87056354), (58203, '04/12/2020', 4, 12, 2020, 214747, 2481, 'United_States_of_America', 'US', 'USA', 329064917.0, 'America', 735.98730065), (58204, '03/12/2020', 3, 12, 2020, 203311, 3190, 'United_States_of_America', 'US', 'USA', 329064917.0, 'America', 727.86519506) ... displaying 10 of 346 total bound parameter sets ... (58541, '01/01/2020', 1, 1, 2020, 0, 0, 'United_States_of_America', 'US', 'USA', 329064917.0, 'America', None), (58542, '31/12/2019', 31, 12, 2019, 0, 0, 'United_States_of_America', 'US', 'USA', 329064917.0, 'America', None)) 2020-12-11 16:31:11,527 INFO sqlalchemy.engine.base.Engine COMMIT 2020-12-11 16:31:11,535 INFO sqlalchemy.engine.base.Engine SELECT name FROM sqlite_master WHERE type='table' ORDER BY name 2020-12-11 16:31:11,535 INFO sqlalchemy.engine.base.Engine ()
我們可以通過sqlite3命令行查看器查看數據,以確保將其正確保存到SQLite文件中。
通過Navicat軟件,打開save_pandas.db文件名的命令來訪問數據庫。然后,使用標准的SQL查詢從Covid19表中獲取所有記錄。

打開表Covid19,執行sql語句
select * from Covid19;
效果如下:

countriesAndTerritories列匹配的 所有數據United_States_of_America都在那里!我們已成功將數據從DataFrame導出到SQLite數據庫文件中。
下一步是什么?
我們只是將數據從CSV導入到pandas DataFrame中,選擇了該數據的一個子集,然后將其保存到關系數據庫中。
您應該看一下“ 通過研究COVID-19數據學習熊貓” 教程,以了解有關如何從較大的DataFrame中選擇數據子集的更多信息,或者訪問pandas頁面,以獲取Python社區其他成員提供的更多教程。
您還可以通過閱讀Full Stack Python目錄表來了解Python項目中下一步的代碼 。
本文參考鏈接:
https://www.fullstackpython.com/blog/export-pandas-dataframes-sqlite-sqlalchemy.html
