Orca項目在DolphinDB之上實現了pandas API,使用戶能更高效地分析處理海量數據。在數據存儲方面,與pandas相比,Orca具有如下顯著優點:python
Orca不只能像pandas同樣在內存中進行計算,將DatFrame中的數據導出到磁盤,也能隨時將DataFrame的數據以及計算結果追加到DolphinDB的數據表中,爲後續的數據查詢、分析提供參考。git
當數據量很是大而又須要保存數據時,在pandas中能夠將整個DataFrame的數據保存到磁盤,在下一次運行Python程序時,用戶再從新將磁盤上的數據加載到內存,這一作法無疑須要在導入和導出操做上耗費大量時間。而Orca對數據的存儲與計算過程均進行了優化,用戶只需在程序結束前將數據寫入到DolphinDB數據表,在下一次運行Python程序時,用戶無須從新將整個表的數據加載到內存,也能夠馬上進行分析和計算操做。github
本文將介紹如何經過Orca保存數據。數據庫
1 將數據導出到磁盤api
Orca的Series和DataFrame均支持to_csv
,to_excel
等將數據導出爲固定格式的文件保存到指定路徑的方法。下面對to_csv
進行特殊說明。服務器
to_csv
函數pandas的to_csv
函數的engine參數的取值能夠是‘c’或者‘python’,表示使用哪種引擎進行導入。session
Orca的to_csv
函數的engine參數的取值能夠是{‘c’, ‘python’, ‘dolphindb’},且該參數默認取值爲‘dolphindb’。當取值爲‘dolphindb’時,to_csv
函數會將數據導出到DolphinDB服務器目錄下,且只支持sep和append兩個參數;當取值爲‘python’或‘c’時,to_csv
函數會將數據導出到python客戶端的目錄下,並支持pandas所支持的全部參數。app
示例負載均衡
調用to_csv
函數導出數據,並經過read_csv
函數再將數據導入。如下的腳本中'YOUR_DIR'表示用戶保存csv文件的路徑。因爲數據是隨機生成的,每次執行生成的表數據都不相同,下面的輸出結果僅供參考。dom
>>> YOUR_DIR = "/dolphindb/database" # e.g. data_dir >>> odf = orca.DataFrame({"type": np.random.choice(list("abcde"),10), "value": np.random.sample(10)*100}) >>> odf.to_csv(path_or_buf=YOUR_DIR + "/demo.csv") >>> df1 = orca.read_csv(path=YOUR_DIR + "/demo.csv") >>> df1 # output type value 0 c 93.697510 1 c 64.533273 2 e 11.699053 3 c 46.758312 4 d 0.262836 5 e 30.315109 6 a 72.641846 7 e 60.980473 8 c 89.597063 9 d 25.223624
2 將數據保存到DolphinDB數據表
使用Orca的一個重要場景是,用戶從其餘數據庫系統或是第三方Web API中取得數據後存入DolphinDB數據表中。本節將介紹經過Orca將取到的數據上傳並保存到DolphinDB的數據表中。
Orca數據表按存儲方式分爲三種:
下面以例子的形式解釋這三種表的區別。
能夠經過read_csv
函數導入或者經過DataFrame
函數建立。
read_csv
函數導入以第1節例子中的csv文件爲例,像這樣導入後可以直接訪問表內數據的表,咱們稱之爲Orca內存表。
>>> df1 = orca.read_csv(path=YOUR_DIR + "/demo.csv") >>> df1 # output type value 0 c 93.697510 1 c 64.533273 2 e 11.699053 3 c 46.758312 4 d 0.262836 5 e 30.315109 6 a 72.641846 7 e 60.980473 8 c 89.597063 9 d 25.223624
DataFrame
函數建立經過orca.DataFrame函數建立的內存表,也可以直接訪問表內數據:
>>> df = orca.DataFrame({"date":orca.date_range("20190101", periods=10),"price":np.random.sample(10)*100}) >>> df # output date price 0 2019-01-01 35.218404 1 2019-01-02 24.066378 2 2019-01-03 6.336181 3 2019-01-04 24.786319 4 2019-01-05 35.021376 5 2019-01-06 14.014935 6 2019-01-07 7.454209 7 2019-01-08 86.430214 8 2019-01-09 80.033767 9 2019-01-10 45.410883
磁盤表分爲本地磁盤表和磁盤分區表,其中本地磁盤表與內存表的區別就在於本地磁盤表是保存在磁盤上的內存表,不須要進行分區。而磁盤分區表則是保存在磁盤上的分區表,如下具體解釋本地磁盤表。
經過read_table
函數能夠在Orca中加載本地磁盤表。
Orca提供read_table
函數,經過該函數指定DolphinDB數據庫和表名來加載DolphinDB數據表的數據,該函數支持的參數以下:
請注意:
read_table
函數要求所要導入的數據庫和表在DolphinDB服務器上已經存在,若只存在數據庫和沒有建立表,則不能將數據成功導入到Python中。
從函數定義能夠看出,read_table函數能夠用於導入Orca的分區表,可是當導入的表是DolphinDB的磁盤表時,Orca會將表數據全都加載到內存,做爲Orca內存表以供訪問。
示例
假設DolphinDB Server上已有數據庫和表以下,如下的腳本中'YOUR_DIR'表示用戶保存磁盤表的路徑。
rows=10 tdata=table(rand(`a`b`c`d`e, rows) as type, rand(100.0, rows) as value) saveTable(YOUR_DIR + "/testOnDiskDB", tdata, `tb1)
腳本中建立的數據庫的路徑爲YOUR_DIR + "/testOnDiskDB",存儲的表名爲"tb1"。在Python客戶端中,咱們能夠經過read_table
函數將這個磁盤表表加載到內存中,存放在一個Orca的DataFrame對象裏。
>>> df = orca.read_table(YOUR_DIR + "/testOnDiskDB", "tb1")
將上述過程整合成的Python中可執行的腳本以下:
>>> s = orca.default_session() >>> data_dir = "/dolphindb/database" # e.g. data_dir >>> tableName = "tb1" >>> create_onDisk_table = """ rows=10 tdata=table(rand(`a`b`c`d`e, rows) as type, rand(100.0, rows) as value) saveTable("{YOUR_DIR}" + "/testOnDiskDB", tdata, `{tbName}) """.format(YOUR_DIR=data_dir, tbName=tableName) >>> s.run(create_onDisk_table) >>> df = orca.read_table(data_dir + "/testOnDiskDB", tableName) >>> df # output type value 0 e 42.537911 1 b 44.813589 2 d 28.939636 3 a 73.719393 4 b 66.576416 5 c 36.265364 6 a 43.936593 7 e 56.951759 8 e 4.290316 9 d 29.229366
上述腳本中,咱們使用的defalut_session
實際上就是經過orca.connect
函數建立的會話,在Python端,咱們能夠經過這個會話與DolphinDB服務端進行交互。關於更多功能,請參見DolphinDB Python API。
分佈式表是DolphinDB推薦在生產環境下使用的數據存儲方式,它支持快照級別的事務隔離,保證數據一致性。分佈式表支持多副本機制,既提供了數據容錯能力,又能做爲數據訪問的負載均衡。在Orca中,能夠經過read_csv函數指定分佈式表導入數據並加載分佈式表信息,或者經過read_table函數加載分佈式表信息。
read_csv
函數Orca在調用read_csv
函數時指定db_handle, table_name以及partition_columns參數,能夠直接將數據直接導入DolphinDB的DFS表,關於read_csv
函數將數據導入分區表的詳細介紹請參考Orca的分區表。
示例
請注意只有啓用enableDFS=1的集羣環境或者DolphinDB單例模式才能使用分佈式表。
以第1節例子中的csv文件爲例,咱們在DolphinDB服務端建立一個DFS數據庫,將demo.csv導入數據庫:
dbPath="dfs://demoDB" login('admin', '123456') if(existsDatabase(dbPath)) dropDatabase(dbPath) db=database(dbPath, VALUE, `a`b`c`d`e)
請注意:以上腳本須要在DolphinDB服務端執行,在Python客戶端中則能夠經過DolphinDB Python API執行腳本。
在Python客戶端中調用Orca的read_csv函數,指定數據庫db_handle爲DFS數據庫"dfs://demoDB",指定表名table_name爲"tb1"和進行分區的列partition_columns爲"type",將數據導入到DolphinDB分區表,這時,read_csv函數返回的是一個表示DolphinDB分區表的對象,客戶端並不能直接訪問表內的數據。在後續的計算中,Orca纔會從服務端下載計算所需數據。
>>> df = orca.read_csv(path=YOUR_DIR + "/demo.csv", dtype={"type": "SYMBOL", "value": np.float64}, db_handle="dfs://demoDB", table_name="tb1", partition_columns="type") >>> df # output <'dolphindb.orca.core.frame.DataFrame' object representing a column in a DolphinDB segmented table>
若須要查看df內的數據,能夠調用to_pandas
函數查看,因爲分區表的數據分佈在各個分區上,調用to_pandas
函數會將全部數據下載到客戶端,且按照分區的順序輸出數據。
>>> df.to_pandas() # output type value 0 a 72.641846 1 c 93.697510 2 c 64.533273 3 c 46.758312 4 c 89.597063 5 d 0.262836 6 d 25.223624 7 e 11.699053 8 e 30.315109 9 e 60.980473
將上述過程整合成的Python中可執行的腳本以下:
>>> YOUR_DIR = "/dolphindb/database" # e.g. data_dir >>> s = orca.default_session() >>> dfsDatabase = "dfs://demoDB" >>> create_database = """ dbPath='{dbPath}' login('admin', '123456') if(existsDatabase(dbPath)) dropDatabase(dbPath) db=database(dbPath, VALUE, `a`b`c`d`e) """.format(dbPath=dfsDatabase) >>> s.run(create_database) >>> df=orca.read_csv(path=YOUR_DIR +"/demo.csv", dtype={"type": "SYMBOL", "value": np.float64}, db_handle=dfsDatabase, table_name="tb1", partition_columns="type")
請注意:在經過read_csv函數指定數據庫導入數據以前,須要確保在DolphinDB服務器上已經建立了對應的數據庫。read_csv函數根據指定的數據庫,表名和分區字段導入數據到DolphinDB數據庫中,若表存在則追加數據,若表不存在則建立表而且導入數據。
read_table
函數加載分區表信息若Orca調用read_table
函數加載的是磁盤分區表或者dfs分區表,則數據不會在加載的時候被下載,以上述例子中建立的dfs分區表爲例:
>>> df = orca.read_table("dfs://demoDB", "tb1") >>> df # output <'orca.core.frame.DataFrame' object representing a column in a DolphinDB segmented table>
對df進行計算,則下載數據進行計算:
>>> df.groupby("type").mean() # output value type a 72.641846 c 73.646539 d 12.743230 e 34.331545
下面介紹向Orca的數據表寫數據的過程。
2.1 保存數據到Orca內存表
pandas提供的append函數用於將一個DataFrame追加到另外一個Dataframe,並返回一個新的DataFrame,不會對原有的DataFrame進行修改。在Orca中,append函數還支持inplace參數,當它爲True時,會將追加的數據保存到Dataframe中,對原有的DataFrame進行了修改,這個過程就是將數據追加到Orca的內存表中。
>>> df1 = orca.DataFrame({"date":orca.date_range("20190101", periods=10), "price":np.random.sample(10)*100}) >>> df1 # output date price 0 2019-01-01 17.884136 1 2019-01-02 57.840625 2 2019-01-03 29.781247 3 2019-01-04 89.968203 4 2019-01-05 19.355847 5 2019-01-06 74.684634 6 2019-01-07 91.678632 7 2019-01-08 93.927549 8 2019-01-09 47.041906 9 2019-01-10 96.810450 >>> df2 = orca.DataFrame({"date":orca.date_range("20190111", periods=3), "price":np.random.sample(3)*100}) >>> df2 # output date price 0 2019-01-11 26.959939 1 2019-01-12 75.922693 2 2019-01-13 93.012894 >>> df1.append(df2, inplace=True) >>> df1 # output date price 0 2019-01-01 17.884136 1 2019-01-02 57.840625 2 2019-01-03 29.781247 3 2019-01-04 89.968203 4 2019-01-05 19.355847 5 2019-01-06 74.684634 6 2019-01-07 91.678632 7 2019-01-08 93.927549 8 2019-01-09 47.041906 9 2019-01-10 96.810450 0 2019-01-11 26.959939 1 2019-01-12 75.922693 2 2019-01-13 93.012894
請注意:當設置inplace參數爲True時,index_ignore參數的值不容許設置,只能爲False。
2.2 保存數據到Orca磁盤表
Orca提供兩種方式修改磁盤表的數據:
save_table
函數append
函數2.2.1 保存數據到Orca本地磁盤表
Orca提供save_table
函數,用於保存數據到磁盤表和分佈式表,該函數參數以下:
首先經過read_table
函數導入上文中建立的磁盤表。
>>> df = orca.read_table(YOUR_DIR + "/testOnDiskDB", "tb1") >>> df # output type value 0 e 42.537911 1 b 44.813589 2 d 28.939636 3 a 73.719393 4 b 66.576416 5 c 36.265364 6 a 43.936593 7 e 56.951759 8 e 4.290316 9 d 29.229366
生成要追加的數據,追加數據到df,並經過save_table
保存數據。
>>> df2 = orca.DataFrame({"type": np.random.choice(list("abcde"),3), "value": np.random.sample(3)*100}) >>> df.append(df2, inplace=True) >>> df # output type value 0 e 42.537911 1 b 44.813589 2 d 28.939636 3 a 73.719393 4 b 66.576416 5 c 36.265364 6 a 43.936593 7 e 56.951759 8 e 4.290316 9 d 29.229366 0 d 20.702066 1 c 21.241707 2 a 97.333201 >>> orca.save_table(YOUR_DIR + "/testOnDiskDB", "tb1", df)
須要注意的是,對於磁盤表,若該指定的表名不存在於數據庫中,save_table
會建立對應的表;若數據庫中已有同名的表,save_table
會覆蓋該表。
2.2.2 保存數據到Orca磁盤分區表
磁盤分區表與分佈式表的差別就在於分佈式表的數據庫路徑以"dfs://"開頭,而磁盤分區表的數據庫路徑是本地的一個絕對路徑。
save_table
函數將數據保存到磁盤分區表直接調用save_table
函數,能夠將一個內存表以分區的形式保存到磁盤上,與磁盤非分區表相似,若表已存在,會覆蓋該表。
>>> df2 = orca.DataFrame({"type": np.random.choice(list("abcde"),3), "value": np.random.sample(3)*100}) >>> orca.save_table(YOUR_DIR + "/testOnDisPartitionedkDB", "tb1", df2) >>> df = orca.read_table(YOUR_DIR + "/testOnDisPartitionedkDB", "tb1") >>> df # output type value 0 d 86.549417 1 e 61.852710 2 d 28.747059
append
函數追加數據到磁盤分區表對於磁盤分區表,調用append
函數能夠向磁盤分區表追加數據。
首先,在DolphinDB中建立磁盤分區表:
dbPath=YOUR_DIR + "/testOnDisPartitionedkDB" login('admin', '123456') if(existsDatabase(dbPath)) dropDatabase(dbPath) db=database(dbPath, VALUE, `a`b`c`d`e)
在Python客戶端中導入第1節例子中的csv文件
>>> df = orca.read_csv(path=YOUR_DIR + "/demo.csv", dtype={"type": "SYMBOL", "value": np.float64}, db_handle=YOUR_DIR + "/testOnDisPartitionedkDB", table_name="tb1", partition_columns="type") >>> df.to_pandas() # output type value 0 a 72.641846 1 c 93.697510 2 c 64.533273 3 c 46.758312 4 c 89.597063 5 d 0.262836 6 d 25.223624 7 e 11.699053 8 e 30.315109 9 e 60.980473
調用append
函數向df表追加數據,從新加載該磁盤分區表,發現數據已經追加:
>>> df2 = orca.DataFrame({"type": np.random.choice(list("abcde"),3), "value": np.random.sample(3)*100}) >>> df.append(df2,inplace=True) >>> df = orca.read_table(YOUR_DIR + "/testOnDisPartitionedkDB", "tb1") >>> df.to_pandas() # output type value 0 a 72.641846 1 c 93.697510 2 c 64.533273 3 c 46.758312 4 c 89.597063 5 c 29.233253 6 c 38.753028 7 d 0.262836 8 d 25.223624 9 d 55.085909 10 e 11.699053 11 e 30.315109 12 e 60.980473
將上述過程整合成Python端的可執行腳本以下:
>>> YOUR_DIR = "/dolphindb/database" # e.g. data_dir >>> s = orca.default_session() >>> create_database = """ dbPath='{dbPath}' login('admin', '123456') if(existsDatabase(dbPath)) dropDatabase(dbPath) db=database(dbPath, VALUE, `a`b`c`d`e) """.format(dbPath=YOUR_DIR + "/testOnDisPartitionedkDB") >>> s.run(create_database) >>> df = orca.read_csv(path=YOUR_DIR + "/demo.csv", dtype={"type": "SYMBOL", "value": np.float64}, db_handle=YOUR_DIR + "/testOnDisPartitionedkDB", table_name="tb1", partition_columns="type") >>> df2 = orca.DataFrame({"type": np.random.choice(list("abcde"),3), "value": np.random.sample(3)*100}) >>> df.append(df2,inplace=True) >>> df = orca.read_table(YOUR_DIR + "/testOnDisPartitionedkDB", "tb1")
2.3 保存數據到Orca分佈式表
append
函數追加數據到分佈式表對於分佈式表,能夠直接經過append
函數追加數據。
首先,在DolphinDB中建立分佈式表:
dbPath="dfs://demoDB" login('admin', '123456') if(existsDatabase(dbPath)) dropDatabase(dbPath) db=database(dbPath, VALUE, `a`b`c`d`e)
在Python客戶端中導入第1節例子中的csv文件:
>>> df = orca.read_csv(path=YOUR_DIR + "/demo.csv", dtype={"type": "SYMBOL", "value": np.float64}, db_handle="dfs://demoDB", table_name="tb1", partition_columns="type") >>> df.to_pandas() # output type value 0 a 72.641846 1 c 93.697510 2 c 64.533273 3 c 46.758312 4 c 89.597063 5 d 0.262836 6 d 25.223624 7 e 11.699053 8 e 30.315109 9 e 60.980473
調用append
函數向df表追加數據,從新加載該分佈式表,發現數據已經追加:
>>> df2 = orca.DataFrame({"type": np.random.choice(list("abcde"),3), "value": np.random.sample(3)*100}) >>> df.append(df2,inplace=True) >>> df = orca.read_table("dfs://demoDB", "tb1") >>> df.to_pandas() # output type value 0 a 72.641846 1 a 55.429765 2 a 51.230669 3 c 93.697510 4 c 64.533273 5 c 46.758312 6 c 89.597063 7 c 71.821263 8 d 0.262836 9 d 25.223624 10 e 11.699053 11 e 30.315109 12 e 60.980473
將上述過程整合成Python端的可執行腳本以下:
>>> YOUR_DIR = "/dolphindb/database" # e.g. data_dir >>> s = orca.default_session() >>> create_database = """ dbPath='{dbPath}' login('admin', '123456') if(existsDatabase(dbPath)) dropDatabase(dbPath) db=database(dbPath, VALUE, `a`b`c`d`e) """.format(dbPath="dfs://demoDB") >>> s.run(create_database) >>> df = orca.read_csv(path=YOUR_DIR + "/demo.csv", dtype={"type": "SYMBOL", "value": np.float64}, db_handle="dfs://demoDB", table_name="tb1", partition_columns="type") >>> df2 = orca.DataFrame({"type": np.random.choice(list("abcde"),3), "value": np.random.sample(3)*100}) >>> df.append(df2,inplace=True) >>> df = orca.read_table("dfs://demoDB", "tb1")
save_table
函數追加數據到分佈式表與磁盤表不一樣的是,對分佈式表調用save_table
函數,能夠直接追加數據,而不是覆蓋數據。且與append
函數相比,save_table
函數無需先在客戶端經過read_table
得到將要追加的表信息,就直接在DolphinDB服務端上追加數據的操做。
下面的例子中,經過save_table
函數直接將內存表的數據追加到指定表:
>>> df2 = orca.DataFrame({"type": np.random.choice(list("abcde"),3), "value": np.random.sample(3)*100}) >>> orca.save_table("dfs://demoDB", "tb1", df2) >>> df = orca.read_table("dfs://demoDB", "tb1") >>> df.to_pandas() # output type value 0 a 72.641846 1 a 55.429765 2 a 51.230669 3 b 40.724064 4 c 93.697510 5 c 64.533273 6 c 46.758312 7 c 89.597063 8 c 71.821263 9 c 93.533380 10 d 0.262836 11 d 25.223624 12 d 47.238962 13 e 11.699053 14 e 30.315109 15 e 60.980473
3 小結
2. 對於普通磁盤表之外的表,inplce參數置爲True時,append方法將追加數據。
3. save_table函數,對於本地磁盤表會覆蓋原表;對於dfs表,數據會被追加到表中