DolphinDB使用案例21:orca入门及底层实现

  • Orca

    OrcaDolphinDB Python API下的一个模块。充分衔接PandasDolphinDB服务端。

    《DolphinDB基础概念理解:Orca》

  • Orca结构

    # 连接Python与DolphinDB数据库
    import dolphindb.orca as orca
    orca.connect(MY_HOST, MY_PORT, MY_USERNAME, MY_PASSWORD) 
    

    DolphinDB使用案例21:orca入门及底层实现_第1张图片

    Orca是一个module,内部包含core这个modulecore模块下包含18个类seriesdatetime…,每个类又有各自的方法。

    上述描述针对Orca version 0.10.0

    DolphinDB使用案例21:orca入门及底层实现_第2张图片

  • Orca使用方法

    • 创建Series类(是orca.Series)
    import dolphindb.orca as orca
    orca.connect('localhost', 8848, 'admin', '123456')
    s = orca.Series([1,2,3])
    print(s)
    print(type(s))
    

    DolphinDB使用案例21:orca入门及底层实现_第3张图片

    • 创建DataFrame类(是orca.DataFrame)
      1. 通过传入字典创建

        DolphinDB使用案例21:orca入门及底层实现_第4张图片

      2. 通过传入pandas.DataFrame创建

        DolphinDB使用案例21:orca入门及底层实现_第5张图片

        方法 意义 备注
        odf.head() 查看orca对象的顶部数据 直接打印一个Orca对象时,服务端通常会把对应的整个DolphinDB数据传送到本地,这样做可能会造成不必要的网络开销
        odf.index 查看数据索引
        odf.columns 查看数据列名
        odf.to_pandas 把一个Orca DataFrame对象转换成Pandas DataFrame
        odf.read_csv() 加载csv文件 要求csv文件位于DolphinDB服务端,所给的路径是它在服务端的路径
  • Orca使用原则

    DolphinDB使用案例21:orca入门及底层实现_第6张图片

    orca使用DolphinDB Python API服务端通信。

    实际的数据储存查询计算都发生在服务端orca仅仅是一个提供了类似pandas接口的客户端

    因此,系统的瓶颈常常在网络通信上。用户在编写高性能的orca程序时,需要关注如何优化程序,以减少网络通信量。

    • 减少to_pandas和from_pandas的调用

      调用to_pandas函数将orca对象转化为pandas对象时,服务端会把整个DolphinDB对象传输到客户端。如果没有必要,一般应该减少这样的转换。此外,以下操作会隐式调用to_pandas,因此也需要注意:

      • 打印一个表示非分区表的Orca DataFrameSeries
      • 调用to_numpy或访问values
      • 调用Series.unique, orca.qcut等返回numpy.ndarray的函数
      • 调用plot相关函数画图
      • 将Orca对象导出为第三方格式的数据

      类似地,from_pandas会将本地的pandas对象上传到DolphinDB服务端。当orca.DataFrameorca.Seriesdata参数为非Orca对象时,也会先在本地创建一个pandas对象,然后上传到DolphinDB服务端。

      在编写Orca代码时,应该考虑减少来回的网络通信。

    • Orca并非总是立刻求值

      Orca采用了惰性求值策略,某些操作不会立刻在服务端计算,而是转化成一个中间表达式,直到真正需要时才发生计算。

      需要触发计算时,用户应调用compute函数。

      例如,对同一个DataFrame中的列进行四则运算,不会立刻触发计算:

      df = orca.DataFrame({"a": [1, 2, 3], "b": [10, 10, 30]})
      c = df["a"] + df["b"]
      

      DolphinDB使用案例21:orca入门及底层实现_第7张图片

      d = df[df["a"] > 2] # 条件过滤查询不会立刻触发计算
      c = df.groupby("b").cumsum() # 分组后的聚合函数
      c = df.groupby("b").transform("count")
      
    • 操作同一个DataFrame里的列以提高性能

      如果操作的是同一个DataFrame里的列,Orca可以将这些操作优化为单个DolphinDB SQL表达式。这样的操作会有较高性能。例如:

      • 逐元素计算:df.x + df.y, df * df, df.x.abs()
      • 过滤行的操作:df[df.x > 0]
      • isin操作:df[df.x.isin([1, 2, 3])]
      • 时间类型/字符串访问器:df.date.dt.month
      • 用同样长度的计算结果赋值:df["ret"] = df["ret"].abs()

      DataFrame是经过过滤的结果时,如果过滤的条件完全相同(在Python中是同一个对象,即调用id函数获得的值相同),也能做到这样的优化。

      以下脚本可以优化:

      df[df.x > 0] = df[df.x > 0] + 1
      

      上述脚本中,等号两边的过滤条件虽然看似相同,但在Python中实际产生了两个不同的对象。在DolphinDB引擎中会先执行一个select语句,再执行一个update语句。如果将这个过滤条件赋值给一个中间变量Orca就可以将上述代码优化为单个DolphinDBupdate语句:

      df_x_gt_0 = df.x > 0
      df[df_x_gt_0] = df[df_x_gt_0] + 1
      
    • 修改表数据的限制

      DolphinDB中,一个表的列的数据类型无法修改。

      此外,一个非内存表(例如DFS表)有这些限制:

      • 无法添加新的列
      • 无法通过update语句修改其中的数据

      而一个分区表有这些限制:

      • 不同分区的数据之间没有严格的顺序关系
      • 无法通过update语句将一个向量赋值给一个列

      因此,当用户尝试对一个Orca对象进行修改时,操作可能会失败。Orca对象的修改有以下规则:

      • 更新的数据类型不兼容,例如将一个字符串赋值给一个整数列时,会抛出异常
      • 为一个表示非内存表的orca对象添加列,或修改其中的数据时,会将这个表复制为内存表中,并给出一个警告
      • 自动为一个表示分区表的orca对象添加默认索引时,并不会真正添加一个列,此时会给出一个警告
      • 为一个表示分区表的orca对象设置或添加一个列时,如果这个列是一个Pythonnumpy数组,或一个表示内存表的orca Series时,会抛出异常

      当尝试给表示非内存表的orca对象添加列,或修改其中数据时,数据会复制为内存表,然后再进行修改。当处理海量数据时,可能导致内存不足。因此应该尽量避免对这类orca对象的修改操作。

      Orca部分函数不支持inplace参数。因为inplace涉及到修改数据本身。

      Orca目前不支持rank函数的method="average"na_option="keep"参数。

    • 过滤时用逗号(,)替代&符号
    • 如何实现DolphinDB的context by语句
  • Orca客户端与DolphinDB服务端

    DolphinDB服务端并不能识别Python函数(自定义或内置),只能识别dolphindb模块内(包括orca)的函数以及DolphinDB语言脚本

  • References

  1. Github >> Orca

你可能感兴趣的:(TSDB,DolphinDB,KDB+)