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表,数据会被追加到表中