乾貨丨Orca寫數據教程

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_csvto_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數據表按存儲方式分爲三種:

  • 內存表:數據僅保存在內存中,存取速度最快,可是節點關閉後數據就不存在了。
  • 本地磁盤表:數據保存在本地磁盤上。能夠從磁盤加載到內存。
  • 分佈式表:數據存儲在DolphinDB服務端,並未加載到內存,客戶端只是得到了數據庫和表的信息,經過DolphinDB的分佈式計算引擎,仍然能夠像本地表同樣作統一查詢。

下面以例子的形式解釋這三種表的區別。

  • 內存表

能夠經過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數據表的數據,該函數支持的參數以下:

  • database:數據庫名稱
  • table:表名
  • partition:須要導入的分區,可選參數
請注意:  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函數,用於保存數據到磁盤表和分佈式表,該函數參數以下:

  • db_path:數據庫路徑
  • table_name:表名
  • df:須要保存的表
  • ignore_index:是否忽略index追加數據

首先經過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 小結

  1. Orca的to_csv函數在engine='dolphindb'的默認狀態下只支持sep和append兩個參數。

2. 對於普通磁盤表之外的表,inplce參數置爲True時,append方法將追加數據。

3. save_table函數,對於本地磁盤表會覆蓋原表;對於dfs表,數據會被追加到表中

相關文章
相關標籤/搜索