Orca與pandas的差別是什麼?

因爲DolphinDB是一款相對成熟的高性能分佈式時序數據庫,其底層對一些方法的處理機制已經成型,這就決定了Orca在某些細節方面會與pandas存在差別。爲了方便用戶更快地瞭解和掌握Orca,本文按照如下幾個模塊來系統地介紹Orca與pandas存在的差別。html

  1. 數據類型的差別
  2. 通用函數的差別
  3. Input/output的差別
  4. Series、DataFrame的差別
  5. Index Objects的差別
  6. GroupBy的差別
  7. Resampling的差別
  8. Orca分區表的特殊差別

1 數據類型的差別python

  • DolphinDB支持CHAR, SHORT, INT, LONG等不一樣字節數的整數類型,整數字面量默認解析爲32位INT類型,而pandas的整數字面量默認解析爲64位。
  • DolphinDB支持STRING和SYMBOL兩種字符串類型,STRING類型能夠進行max, min等比較運算,但SYMBOL不容許。而pandas中的字符串類型的底層存儲是np.object。pandas也提供了通過優化的category類型,使用整數做爲底層存儲,對於取值範圍有限的數據,能減小內存佔用。DolphinDB的SYMBOL類型能實現相似的功能。但pandas容許將任何數據類型的數據轉換爲category類型,而DolphinDB只容許字符串類型。
  • DolphinDB支持多種不一樣單位的日期和時間類型,包括DATE, MINUTE, SECOND, TIME, NANOTIME等,而pandas底層的日期時間存儲使用np.datetime64[ns]類型,以freq表示時間單位
  • DolphinDB要求表一列中元素的數據類型必須相同,而pandas容許一個Series的中的數據有不一樣數據類型。所以,DolphinDB中字符串類型的NULL值其實是一個空字符串,而pandas中字符串類型的空值是np.NaN。

2 通用函數的差別git

Orca提供如下通用函數:github

  • connect :將會話鏈接到DolphinDB服務器
  • merge: 鏈接兩個DataFrame
  • concat :按照columns對齊鏈接兩個DataFrame
  • date_range :建立時間序列
  • to_datetime :將字符串轉換成時間類型
  • isna :判斷是不是空值
  • isnull :判斷是不是空值
  • notna :判斷是否不是空值
  • notnull :判斷是否不是空值

下面對connect函數和save_table函數加以說明:正則表達式

connect函數數據庫

因爲Orca是基於DolphinDB Python API開發的,爲此,Orca提供connect函數來創建一個與DolphinDB服務器的鏈接,並且在開始使用Orca函數以前,必須首先調用該函數建立鏈接。api

>>> import dolphindb.orca as orca
>>> orca.connect(MY_HOST, MY_PORT, MY_USERNAME, MY_PASSWORD)

save_table函數服務器

該函數的具體意義及用法請參見Orca寫數據教程session

3 Input/output的差別app

Orca如今支持的Input/output函數有:read_csvread_table

3.1 read_csv函數

下面詳細介紹Orca的read_csv函數與pandas的read_csv函數的差別。

  • engine參數

pandas的read_csv函數的engine參數的取值能夠是‘c’或者‘python’,表示使用哪種引擎進行導入。

而Orca的read_csv函數的engine參數的取值能夠是{‘c’, ‘python’, ‘dolphindb’},且該參數默認取值爲‘dolphindb’。當取值爲‘dolphindb’時,read_csv函數會在DolphinDB服務器目錄下尋找要導入的數據文件。當取值爲‘python’或‘c’時,read_csv函數會在python客戶端的目錄下尋找要導入的數據文件。

注意,當engine參數設置爲‘python’或者‘c’時,Orca的 read_csv函數至關於調用了pandas的 read_csv函數進行導入。下面列出的差別均是在engine參數設置爲‘dolphindb’的前提下的差別。

當engine參數取值爲‘dolphindb’時,Orca的read_csv函數目前支持的參數以下:

read_csv(path, sep=',', delimiter=None, names=None,  index_col=None,engine='dolphindb', usecols=None, squeeze=False, prefix=None, dtype=None, partitioned=True, db_handle=None, table_name=None, partition_columns=None, *args, **kwargs)
  • dtype參數

在pandas中,read_csv函數支持dtype參數,該參數接收一個字典,鍵是列名,值是Python原生類型(bool, int, float, str)或np的dtype(np.bool, np.int8, np.float32, etc.)

例如:

dfcsv = pd.read_csv("path_to/allTypesOfColumns.csv", dtype={"tbool": np.bool, "tchar": np.int8, "tshort": np.int16, "tint": np.int32, "tlong": np.int64, "tfloat": np.float32, "tdouble": np.float64})

與pandas不一樣的是,Orca的read_csv函數的dtype參數還支持以字符串的方式指定DolphinDB的提供的全部數據類型,包括全部時間類型和字符串類型。

例如:

dfcsv = orca.read_csv("path_to/allTypesOfColumns.csv", dtype={"tstring":'STRING', "tsymbol": 'SYMBOL', "date": 'DATE', "second": 'SECOND', "tint": np.int32})
  • sep和delimiter參數

pandas的這兩個參數支持對正則表達式的解析,而Orca的目前沒法支持這一點。

  • partitioned參數

bool類型,該參數爲True時,表示容許分區方式將數據導入(其實是調用DolphinDB的ploadText函數);當該參數爲False時,表示強制以非分區的方式導入數據(其實是調用DolphinDB的loadText函數)。

注意:Orca的分區表與Orca的內存表相比,在操做時也存在許多差別,具體見第8節Orca分區表的特殊差別。若您的數據量不是很大,且在使用Orca時對Orca與pandas的一致性要求更高,請儘可能不要將數據以分區的方式導入。若您數據量極大,對性能要求極高,則建議您採用分區方式導入數據。
  • db_handle, table_name以及partition_columns參數

Orca的read_csv還支持db_handle, table_name和partition_columns這3個參數,這些參數用於在導入數據的時經過指定DolphinDB的數據庫和表等相關信息,將數據導入到DolphinDB的分區表,關於這幾個參數的具體用法與示例請參見第8節Orca分區表的特殊差別。

3.2 read_table函數

在pandas中,read_table函數用於導入一個表格形式的文件。在Orca中,read_table函數用於導入一個DolphinDB的分區表。關於該函數的具體用法與示例請參見第8節Orca分區表的特殊差別。

4 Series、DataFrame的差別

本節主要介紹Orca的Series、DataFrame與pandas的Series、DataFrame的差別。

4.1 Series和DataFrame的建立與修改

  • Series或DataFrame的建立

pandas容許在定義一個Series時不設置name參數,或者使用數字做爲name,這在Orca中的實現至關於在DolphinDB server端新建一個只含有一列的表,而表的列名則不容許爲空值且不能使用數字。所以,在建立Orca的Series而不指定名字時,系統會默認爲該Series自動生成一個名字,固然,用戶不會感知到自動生成的名字,只是會看到Orca拋出的WARNING信息。例如,建立一個名字爲0的series,Orca會拋出WARNING:

>>> a = orca.Series([1, 2, 3, 4], name='0')
# raise warning:
/Orca/Orca/core/common.py:36: NotDolphinDBIdentifierWarning: The DataFrame contains an invalid column name for DolphinDB. Will convert to an automatically generated column name.
  "generated column name.", NotDolphinDBIdentifierWarning)
>>> a
# output
0    1
1    2
2    3
3    4
Name: 0, dtype: int64
  • Series或DataFrame的修改

pandas與Orca的強制轉換機制存在差別。若將一個精度更高的數據類型的值賦值給一個精度更低的Series,在pandas中最終獲得的Series取值爲向下取整,在Orca中則爲四捨五入取整。

>>> ps=pd.Series([10,20,30], index=[0,2,3])
>>> os=orca.Series([10,20,30], index=[0,2,3])
>>> os
# output
Out[26]: 
0    10
2    20
3    30
dtype: int64

# set
>>> os[0]=100.5
>>> os
# output 
0    101
2     20
3     30
dtype: int64

>>> ps[0]=100.5
>>> ps
# output 
0    100
2     20
3     30
dtype: int64
  • 向Series或DataFrame的追加數據

pandas容許經過直接訪問一個不存在的index去增長新的行,可是Orca暫不支持這麼作。

>>> ps = pd.Series([10, 1, 19, -5], index=['a', 'b', 'c', 'd'])
>>> os = orca.Series([10, 1, 19, -5], index=['a', 'b', 'c', 'd'])
>>> ps
# output
a    10
b     1
c    19
d    -5
dtype: int64

>>> ps['e']=1
>>> ps
# output
a    10
b     1
c    19
d    -5
e     1
dtype: int64

>>> os
# output
a    10
b     1
c    19
d    -5
dtype: int64

>>> os['e']=1
>>> os 
# output
# still not changed 
a    10
b     1
c    19
d    -5
dtype: int64

4.2 Series和DataFrame的四則運算

  • 空值的處理

在pandas中,任何數與空值比較,返回都是False,這實際上是Python中NaN比較的規則,而Orca則將空值視爲該類型的最小值。

下例中,分別對pandas和Orca的Series進行條件過濾,能夠看出Orca將NaN值視爲符合過濾條件的值輸出。

>>> ps = pd.Series([1,np.nan,0])
>>> os = orca.Series([1,np.nan,0])
>>> ps[ps<1]
# output
2    0.0
dtype: float64

>>> os[os<1].compute()
# output
1    NaN
2    0.0
dtype: float64
  • 空字符串的處理

pandas的字符串會區分NaN值和空字符串,Orca的空字符串就是NaN。

>>> ps = pd.Series(["","s","a"])
>>> os = orca.Series(["","s","a"])
>>> ps.hasnans
# output
False

>>> os.hasnans
# output
True
  • 零的處理

pandas非零數除以零獲得同符號的無窮大;零除以零獲得NaN。Orca任何數除以零獲得NULL。

>>> ps=pd.Series([1,0,2])
>>> os=orca.Series([1,0,2])

>>>ps.div(0)
# output
0    inf
1    NaN
2    inf
dtype: float64

>>> os.rdiv(0).compute()
# output
0   NaN
1   NaN
2   NaN
dtype: float64

4.3 Sereis和DataFrame的屬性和方法

本小節根據pandas官方提供的SeriesDataFrame的文檔,依次介紹Orca與pandas的不一樣之處。

4.3.1 Attributes and underlying data

除了pandas已經取締的屬性以外,Orca的Series和DataFrame惟一沒有支持的屬性就是memory_usage這一屬性。

4.3.2 Conversion

因爲Orca的優點在於對批量數據讀寫與計算,所以目前在Conversion方面的方法並不完善,如今僅支持Series.to_numpy這一方法。

4.3.3 Indexing, iteration

如下函數可用於orca.DataFrame對象和orca.Series對象:

  • head:返回前n個值
  • tail:返回最後n個值
  • loc:經過index訪問
  • iloc:經過下標訪問
  • where:用NaN填充不符合過濾條件的值
  • mask:用NaN填充符合過濾條件的值

orca.DataFrame對象還具有如下函數:

  • items:遍歷DataFrame
  • iteritems:遍歷DataFrame
  • lookup:根據標籤查詢數據
  • get:訪問某一列

下面對loc,iloc作特殊說明。

  • 經過loc訪問Series和DataFrame

以下所示,Orca暫不支持經過loc去訪問帶有DatetimeIndex的Series和DataFrame。

>>> pdd = pd.DataFrame(
          {'id': [1, 2, 2, 3, 3], 'sym': ['s', 'a', 's', 'a', 's'], 'values': [np.nan, 2, 2, np.nan, 2]},
          index=pd.date_range('20190101', '20190105', 5))
>>> odd = orca.DataFrame(pdd)
>>> pdd
# output
            id sym  values
2019-01-01   1   s     NaN
2019-01-02   2   a     2.0
2019-01-03   2   s     2.0
2019-01-04   3   a     NaN
2019-01-05   3   s     2.0

>>> pdd.loc["20190103":"20190105"]
# output
            id sym  values
2019-01-03   2   s     2.0
2019-01-04   3   a     NaN
2019-01-05   3   s     2.0

>>> odd.loc["20190103":"20190105"]
# raise error

當DataFrame的表中有重複的index時,padas不支持以重複的index值爲slice的下界,而Orca則以第一個出現的重複值爲slice的下界輸出結果。

>>> pdf = pd.DataFrame([[1, 2, 1], [4, 5, 5], [7, 8, 7], [1, 5, 8], [7, 5, 1]], index=[7, 8, 2, 8, 9],
                columns=['max_speed', 'shield', 'size'])
>>> odf = orca.DataFrame([[1, 2, 1], [4, 5, 5], [7, 8, 7], [1, 5, 8], [7, 5, 1]], index=[7, 8, 2, 8, 9],
                    columns=['max_speed', 'shield', 'size'])
>>> pdf
# output
  max_speed  shield  size
7          1       2     1
8          4       5     5
2          7       8     7
8          1       5     8
9          7       5     1
>>> pdf.loc[8:]
# raise error

>>> odf
# output
  max_speed  shield  size
7          1       2     1
8          4       5     5
2          7       8     7
8          1       5     8
9          7       5     1

>>> odf.loc[8:]
# output 
  max_speed  shield  size
8          4       5     5
2          7       8     7
8          1       5     8
9          7       5     1
  • 經過lociloc修改Series和DataFrame中值的類型

pandas能夠經過lociloc更改DataFrame中一個列(Series)的類型。更改其中一個值的類型會致使整列類型變動,也能夠直接經過調用astype函數更改整列的類型。而Orca不容許修改列的類型。

下例中,pandas經過loc去修改Series的值,返回的結果是整列Series變成了np.float64類型,而Orca返回的結果仍然是np.int64類型。經過iloc去訪問Series和DataFrame並進行相似的修改操做一樣會有相似的差別。

>>> ps = pd.Series([10, 20, 30], index=[0, 2, 3])
>>> ps
# output
0    10
2    20
3    30
dtype: int64

>>> os = orca.Series([10, 20, 30], index=[0, 2, 3])
>>> os
# output
0    10
2    20
3    30
dtype: int64

>>>ps.loc[0]=100.5
>>>ps
# output
0    100.5
2     20.0
3     30.0
dtype: float64

>>> os.loc[0]=100.5
>>> os
# output
0    101
2     20
3     30
dtype: int64
  • 經過lociloc修改Series和DataFrame的值

Orca不支持:當index有重複的列,經過一個DataFrame以index對齊的原則去修改另外一個DataFrame的值

>>> pdf = pd.DataFrame([[1, 2, 1], [4, 5, 5], [7, 8, 7], [1, 5, 8], [7, 5, 1]], index=[7, 8, 9, 8, 9],  columns=['max_speed', 'shield', 'size'])
>>> pdf
# output
  max_speed  shield  size
7          1       2     1
8          4       5     5
9          7       8     7
8          1       5     8
9          7       5     1

>>> pdf.loc[7:] = pd.DataFrame([[1, 1, 1], [5, 5, 5], [7, 7, 7], [8, 8, 8], [6, 6, 6]], index=[7, 8, 9, 8, 9], columns=['max_speed', 'shield', 'size'])
>>> pdf
# output
  max_speed  shield  size
7          1       1     1
8          5       5     5
9          7       7     7
8          8       8     8
9          6       6     6

>>> odf = orca.DataFrame([[1, 2, 1], [4, 5, 5], [7, 8, 7], [1, 5, 8], [7, 5, 1]], index=[7, 8, 9, 8, 9], columns=['max_speed', 'shield', 'size'])
>>> odf
# output
    max_speed  shield  size
7          1       2     1
8          4       5     5
9          7       8     7
8          1       5     8
9          7       5     1

>>> odf.loc[7:] = orca.DataFrame([[1, 1, 1], [5, 5, 5], [7, 7, 7], [8, 8, 8], [6, 6, 6]], index=[7, 8, 9, 8, 9], columns=['max_speed', 'shield', 'size'])
# raise error
  • 經過loc向DataFrame新增一行或者一列

pandas支持直接經過loc訪問不存在的index或者columns來新增行或者列,而Orca暫不支持。

>>> pdf = pd.DataFrame([[1, 2, 1], [4, 5, 5], [7, 8, 7], [1, 5, 8], [7, 5, 1]], index=[7, 8, 2, 8, 9],
                columns=['max_speed', 'shield', 'size'])
>>> odf = orca.DataFrame([[1, 2, 1], [4, 5, 5], [7, 8, 7], [1, 5, 8], [7, 5, 1]], index=[7, 8, 2, 8, 9],
                  columns=['max_speed', 'shield', 'size'])
>>> pdf
# output
a    10
b     1
c    19
d    -5
dtype: int64

>>> ps.loc['e']=1
>>> ps
# output
a    10
b     1
c    19
d    -5
e     1
dtype: int64

>>> os
# output
a    10
b     1
c    19
d    -5
dtype: int64

>>> os['e']=1
>>> os 
# output
# still not changed 
a    10
b     1
c    19
d    -5
dtype: int64
  • lociloc暫不支持對MultiIndex的訪問

4.3.4 Binary operator functions

除了combinecombine_first函數以外,Orca支持pandas提供的全部二元函數。可是,Orca的DataFrame或者Series在進行四則運算時,除了本文第2.2小節所說起的差別以外,在四則運算進行的方式上也存在必定差別。

  • 二元運算函數的axis參數

pandas提供的二元運算函數中都有一個axis參數。須要說明的是,Orca的DataFrame和Orca的Series進行二元運算時,不支持aixs參數取值爲'columns'或0

pandas中,對DataFrame和Series進行加法運算,有以下幾種形式:

>>> pdf = pd.DataFrame({'angles': [0, 3, 4], 'degrees': [360, 180, 360]}, index=['circle', 'triangle', 'rectangle'])
>>> pdf + pd.Series([1, 2], index=["angles", "degrees"])
# output
          angles  degrees
circle          1      362
triangle        4      182
rectangle       5      362

>>> pdf.add(pd.Series([1, 2], index=["angles","degrees"]))
# output
          angles  degrees
circle          1      362
triangle        4      182
rectangle       5      362

>>> pdf.add(pd.Series([1, 2, 3], index=['circle', 'triangle', 'rectangle']), axis='index')
# output
            angles  degrees
circle           1      361
triangle         5      182
rectangle        7      363

上例中,直接經過」+「號將DataFrame和Series進行的相加以及不指定axis參數的相加默認按照axis=0的規則進行相加。Orca不支持這種狀況,僅支持axis='index'或1的狀況。所以在Orca中,一個DataFrame能夠這樣與一個Series進行四則運算:

>>> odf = orca.DataFrame({'angles': [0, 3, 4], 'degrees': [360, 180, 360]}, index=['circle', 'triangle', 'rectangle'])
>>> odf.add(orca.Series([1, 2, 3], index=['circle', 'triangle', 'rectangle']), axis='index')
          angles  degrees
circle          1      361
triangle        5      182
rectangle       7      363
注意,在Orca中,只有上述狀況是不支持axis='columns'的,若將一個DataFrame與一個list相加,axis='columns'的狀況仍是支持的:
>>> odf = orca.DataFrame({'angles': [0, 3, 4], 'degrees': [360, 180, 360]}, index=['circle', 'triangle', 'rectangle'])
>>> (odf + [1, 2]).compute()
# output
          angles  degrees
circle         1      362
triangle       4      182
rectangle      5      362
  • 除數是負數

在Orca中,若是負數在除法中做爲除數,返回的結果將是NaN。

以下例所示,在求餘運算中,除數中出現了負數,Orca返回的結果對應位置值爲NaN。

>>> pd.Series([1, 2, 12, 10], index=['a', 'b', 'c', 'd']) % [10, 1, 19, -4]
# output
a     1
b     0
c    12
d    -2
dtype: int64

>>> (orca.Series([1, 2, 12, 10], index=['a', 'b', 'c', 'd']) % [10, 1, 19, -4]).compute()
# output
a     1.0
b     0.0
c    12.0
d     NaN
dtype: float64
  • 求餘運算

pandas支持對浮點數的求餘運算,而Orca暫不支持。

>>> pd.Series([5.5, 10, -4.5, 2.5, np.nan]) % pd.Series([2.5, -4.5, 2.5, np.nan, 3])
# output
0    0.5
1   -3.5
2    0.5
3    NaN
4    NaN
dtype: float64

>>> orca.Series([5.5, 10, -4.5, 2.5, np.nan]) % orca.Series([2.5, -4.5, 2.5, np.nan, 3])
# raise error

4.3.5 Function application, GroupBy & window

如下函數可用於orca.DataFrame對象和orca.Series對象:

  • apply:應用多個函數
  • agg:應用多個聚合函數
  • aggregate:應用多個聚合函數
  • groupby:分組運算
  • rolling:滑動窗口
  • ewm:指數加成滑動

下面介紹一下Orca與pandas仍存在的差別。

  • applyaggaggregate函數

Orca的這三個函數目前僅支持字符串或者一個字典,不支持lambda函數。

>>> ps=pd.Series([1, 2, 12, 10], index=['a', 'b', 'c', 'd'])
>>> ps.apply(lambda x: x + 1)

上面的腳本在Orca中,則須要這樣實現:

>>> os=orca.Series([1, 2, 12, 10], index=['a', 'b', 'c', 'd'])
>>> os.apply("(x->x+1)")

關於這三個函數的具體限制,請參見Orca使用教程

  • groupby函數

Orca的groupby函數目前支持的參數以下:

DataFrame.groupby(self, by=None, level=None, as_index=True, sort=True, squeeze=False, ascending=True, **kwargs)

具體差別請參見文章第6節。

  • rolling函數

Orca的rolling函數目前支持window和on參數。在進行rolling時,若遇到空值,pandas在對應位置返回NaN,而Orca返回上一次計算的結果。

>>> pdf = pd.DataFrame({'id': np.arange(1, 6, 1), 'B': [0, 1, 2, np.nan, 4]})
>>> pdf
# output
  id    B
0   1  0.0
1   2  1.0
2   3  2.0
3   4  NaN
4   5  4.0

>>> pdf.rolling(2, on="id").sum()
# output  
  id    B
0   1  NaN
1   2  1.0
2   3  3.0
3   4  NaN
4   5  NaN

>>> odf = orca.DataFrame({'id': np.arange(1, 6, 1), 'B': [0, 1, 2, np.nan, 4]})
>>> odf
# output 
  id    B
0   1  0.0
1   2  1.0
2   3  2.0
3   4  NaN
4   5  4.0

>>> odf.rolling(2, on="id").sum()
# output
  id    B
0   1  NaN
1   2  1.0
2   3  3.0
3   4  2.0
4   5  4.0

不指定on參數時,則默認按照index進行rolling。

>>> otime = orca.to_datetime(['20130101 09:00:00','20130101 09:00:02','20130101 09:00:03','20130101 09:00:05','20130101 09:00:06'])
>>> odf = orca.DataFrame({'A': ["a", "c", "w", "f", "f"], 'B': [0, 1, 2, np.nan, 4]}, index=orca.Index(data=otime, name='time'))
>>> odf
# output
                    A    B
2013-01-01 09:00:00  a  0.0
2013-01-01 09:00:02  c  1.0
2013-01-01 09:00:03  w  2.0
2013-01-01 09:00:05  f  NaN
2013-01-01 09:00:06  f  4.0

>>> odf.rolling('2s').sum()
# output
                      B
2013-01-01 09:00:00  0.0
2013-01-01 09:00:02  1.0
2013-01-01 09:00:03  3.0
2013-01-01 09:00:05  0.0
2013-01-01 09:00:06  4.0
  • ewm函數

目前Orca的ewm函數可調用如下函數:

  • mean:平均值
  • std:標準差
  • var:方差

4.3.6 Computations/descriptive stats

如下函數可用於orca.DataFrame對象和orca.Series對象:

  • abs:絕對值
  • all:判斷是否爲空
  • any:判斷是否爲空
  • clip:返回介於閾值之間的值
  • clip_lower:返回大於下界的值
  • clip_upper:返回小於上界的值
  • corr:相關性
  • count:非空元素的個數
  • cov:協方差
  • cummax:累計最大值
  • cummin:累計最小值
  • cumprod:累乘
  • cumsum:累加
  • kurt:傾斜度
  • kurtosis:峯度
  • mad:平均絕對利差
  • max:最大值
  • mean:平均值
  • median:中位數
  • min:最小值
  • mode:衆數
  • pct_change:百分比變化率
  • prod:返回乘積
  • product:返回乘積
  • quantile:分位數
  • rank:排名
  • round:規整
  • sem:無偏標準差
  • skew:無偏斜
  • std:標準差
  • sum:求和
  • var:方差
  • nunique:返回非重複值的個數

orca.Series對象還具有如下函數:

  • between:返回介於閾值之間的值
  • unique:返回不重複的值
  • is_unique:判斷是否有重複的值
  • is_monotonic:判斷是否單調
  • is_monotonic_increasing:判斷是否單調遞增
  • is_monotonic_decreasing:判斷是否單調遞減

在Orca提供的函數中,有如下差別。

  • cummaxcummincumprodcumsum函數

這幾個函數在遇到NaN值時會返回NaN,Orca會在NaN值的位置返回前一個計算結果。

>>> pdf = pd.DataFrame([[1, np.nan, 3], [4, np.nan, 6], [7, np.nan, 9], [np.nan, np.nan, 1]], columns=['A', 'B', 'C'])
>>> odf = orca.DataFrame([[1, np.nan, 3], [4, np.nan, 6], [7, np.nan, 9], [np.nan, np.nan, 1]], columns=['A', 'B', 'C'])

>>> pdf.cumsum()
# output
      A   B     C
0   1.0 NaN   3.0
1   5.0 NaN   9.0
2  12.0 NaN  18.0
3   NaN NaN  19.0

>>> odf.cumsum().compute()
# output
      A   B   C
0   1.0 NaN   3
1   5.0 NaN   9
2  12.0 NaN  18
3  12.0 NaN  19
  • rank函數

Orca的rank函數支持的參數以下:

rank(self, ascending=True, rank_from_zero=False, group_num=None)

與pandas相比,該函數新增了兩個參數:rank_from_zero和group_num。

  • rank_from_zero參數

當rank_from_zero取值爲True時,最小的排名爲0,不然最小的排名爲1,和pandas一致。

  • group_num參數

表示排名的分組數,參考DolphinDB文檔中的rank函數。

在計算時,pandas的rank函數會把重複的排名取平均值,而Orca中兩個重複的元素具備相同的排名。在遇到NaN時,pandas返回NaN,而Orca將NaN值視爲最小值。

  • sum函數

在pandas中,對字符串調用sum函數會將多個字符串拼接在一塊兒,Orca則不能對字符串調用sum函數。

  • Series.between函數

pandas中的between是一個三元運算符,上下邊界都支持向量類型。Orca的between函數僅支持標量做爲參數,且不支持inclusive參數。

>>> ps=pd.Series([10, 1, 19, -5])
>>> os=orca.Series([10, 1, 19, -5])
>>> ps.between([1,2,4,5],[15,10,4,5])
# output
0     True
1    False
2    False
3    False
dtype: bool
>>> os.between([1,2,4,5],[15,10,4,5])
# raise error

4.3.7 Reindexing/selection/label manipulation

如下函數可用於orca.DataFrame對象和orca.Series對象:

  • drop_duplicates:刪除重複的值
  • duplicated:判斷是否重複
  • first:返回第一個值
  • head:返回前n個值
  • idxmax:返回index的最大值
  • idxmin:返回index的最小值
  • last:返回最後一個值
  • rename:重命名
  • tail:返回最後n個值

orca.DataFrame對象還具備如下函數:

  • drop:刪除某列
  • reindex:重置index
  • reset_index:重置index
  • set_index:設置index

4.3.8 Reshaping, sorting

Orca目前支持sort_values函數,該函數僅支持ascending參數。在排序中,Orca將NaN值視爲最小值處理。

>>> ps=pd.Series([10, 1, 19, -5, np.nan])
>>> os=orca.Series([10, 1, 19, -5, np.nan])
>>> ps.sort_values()
# output
3    -5.0
1     1.0
0    10.0
2    19.0
4     NaN
dtype: float64

>>> os.sort_values()
# output
4     NaN
3    -5.0
1     1.0
0    10.0
2    19.0
dtype: float64

4.3.9 Serialization / IO / conversion

Orca支持pandas所支持的全部序列化相關函數,並提供一個to_pandas函數,該函數將一個Orca對象轉化爲pandas的對象。

其中,Orca的`to_csv`實現與pandas有所區別,具體請參見Orca寫數據教程

5 Index Objcts的差別

Orca目前支持的Index類型有Index,Int64Index,DatetimeIndex和MultiIndex,下面介紹Index對象所支持的屬性和方法。

5.1 Index的屬性

Orca的Index對象具備如下屬性:

  • values:返回取值
  • is_monotonic:判斷是否單調
  • is_monotonic_increasing:判斷是否單調遞增
  • is_monotonic_decreasing:判斷是否單調遞減
  • is_unique:判斷是否有重複的值
  • hasnans:判斷是否有空值
  • dtype:返回數據類型
  • shape:返回形狀
  • name:返回名字
  • nbytes:返回字節數
  • ndim:返回維度
  • size:返回大小
  • T:返回轉置

5.2 Modifying and computations

Orca的Index對象支持如下函數:

  • max:最大值
  • min:最小值

6 GroupBy的差別

Orca的groupby函數目前僅支持by參數,且只能對DataFrame進行groupby。

如下函數可用於orca.DataFrameGroupBy對象:

  • all:判斷是否爲空
  • any:判斷是否爲空
  • bfill:向後填充
  • count:非空元素的個數
  • cumcount:累計非空元素的個數
  • cummax:累計最大值
  • cummin:累計最小值
  • cumprod:累乘
  • cumsum:累加
  • ffill:向前填充
  • first:返回第一個元素
  • last:返回最後一個元素
  • mad:平均絕對利差
  • max:最大值
  • mean:平均值
  • median:中位數
  • min:最小值
  • ohlc:忽略空值求和
  • pct_change:百分比變化率
  • resample:重採樣
  • size:元素個數
  • sem:無偏標準差
  • skew:無偏斜
  • std:標準差
  • sum:求和
  • var:方差

7 Resampling的差別

Orca支持resample函數,該函數目前支持的參數以下:

  • rule:DateOffset,能夠是字符串或者是dateoffset對象
  • on:時間列,採用該列進行重採樣
  • level:字符串或整數,對於MultiIndex,採用level指定的列進行重採樣

Orca支持的DateOffset以下:

'B':BDay or BusinessDay
'WOM':WeekOfMonth
'LWOM':LastWeekOfMonth
'M':MonthEnd
'MS':MonthBegin
'BM':BMonthEnd or BusinessMonthEnd
'BMS':BMonthBegin or BusinessMonthBegin
'SM':SemiMonthEnd
'SMS':SemiMonthBegin
'Q':QuarterEnd
'QS':QuarterBegin
'BQ':BQuarterEnd
'BQS':BQuarterBegin
'REQ':FY5253Quarter
'A':YearEnd
'AS' or 'BYS':YearBegin
'BA':BYearEnd
'BAS':BYearBegin
'RE':FY5253
'D':Day
'H':Hour
'T' or 'min':Minute
'S':Second
'L' or 'ms':Milli
'U' or 'us':Micro
'N':Nano

8 Orca分區表的特殊差別

8.1 Orca的分區表

pandas做爲全內存計算的分析工具,沒法解決當數據量過大時帶來的內存不足,計算效率低下等問題。DolphinDB是一個分佈式時序數據庫,而且內置了豐富的計算和分析功能。它能夠將TB級的海量數據存儲在多臺物理機器上,充分利用CPU,對海量數據進行高性能分析計算。

Orca做爲基於DolphinDB開發的分佈式pandas接口,其最大的優點就是在語法和pandas保持一致的前提下很好地解決了pandas的瓶頸:大數據場景下的性能問題。而這一問題的解決,則依賴於DolphinDB分區表。在Orca中,咱們也引入Orca分區表的概念。

在下列狀況下,數據將以分區表的形式處理:

  • read_csv函數

在本文第3節中曾說起,指定partitioned參數爲True會將數據以分區的方式導入DolphinDB。下面,咱們對第3節中提到的關於分區表的參數加以說明。

DolphinDB支持經過多種方式將數據導入DolphinDB數據庫,Orca在調用read_csv函數時指定db_handle, table_name以及partition_columns參數,本質上是調用DolphinDB的loadTextEx函數,經過這種方式,咱們能夠直接將數據直接導入DolphinDB的分區表。

請注意:DolphinDB的分區表能夠保存在本地磁盤,也能夠保存在dfs上,磁盤分區表與分佈式表的差別就在於分佈式表的數據庫路徑以"dfs://"開頭,而磁盤分區表的數據庫路徑是本地的一個絕對路徑。爲了不涉及本地路徑,如下的示例以分佈式表爲主。

示例

請注意只有啓用enableDFS=1的集羣環境或者DolphinDB單例模式才能使用分佈式表。

下面咱們經過執行DolphinDB腳本生成模擬數據,並保存爲csv文件,如下的腳本中'YOUR_DIR'表示用戶保存csv文件的路徑。

rows=100
tdata=table(rand(`a`b`c`d`e, rows) as type, rand(100, rows) as value)
saveText(tdata, YOUR_DIR+"/testImport.csv")

根據模擬數據,咱們在DolphinDB服務端建立一個DFS數據庫:

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分區表,並返回一個表示DolphinDB數據表的對象給df,用於後續計算。

>>> df = orca.read_csv(path=data_dir+"/testImport.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>

將上述過程整合成的Python中可執行的腳本以下:

>>> s = orca.default_session()
>>> data_dir = "/dolphindb/database" # e.g. data_dir
>>> create_csv = """
rows=100
tdata=table(rand(`a`b`c`d`e, rows) as type, rand(100.0, rows) as value)
saveText(tdata, "{YOUR_DIR}"+"/testImport.csv")""".format(YOUR_DIR= data_dir)
>>> 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_csv)
>>> s.run(create_database)
>>> df=orca.read_csv(path=data_dir+"/testImport.csv", dtype={"type": "SYMBOL", "value": np.float64},
                     db_handle=dfsDatabase, table_name="tb1", partition_columns="type")

上述腳本中,咱們使用的defalut_session實際上就是經過orca.connect函數建立的會話,在Python端,咱們能夠經過這個會話與DolphinDB服務端進行交互。關於更多功能,請參見DolphinDB Python API。

請注意:在經過 read_csv函數指定數據庫導入數據以前,須要確保在DolphinDB服務器上已經建立了對應的數據庫。 read_csv函數根據指定的數據庫,表名和分區字段導入數據到DolphinDB數據庫中,若表存在則追加數據,若表不存在則建立表而且導入數據。
  • read_table函數

經過read_table函數指定DolphinDB數據庫和表名來使用DolphinDB數據表的數據。須要注意的是,read_table函數要求所要導入的數據庫和表在DolphinDB服務器上已經存在,若只存在數據庫和沒有建立表,則不能將數據成功導入到Python中。

示例

假設DolphinDB Server上已有數據庫和表以下:

tdata=table(1..5 as id, rand(2.0,5) as value)
db=database('dfs://testRead',VALUE,1..5)
tb=db.createPartitionedTable(tdata,`tb1,`id)
tb.append!(tdata)

其中,數據庫名稱爲"dfs://testRead",建立的分區表名爲"tb1"。咱們能夠經過read_table函數將一個分區表加載到Python應用程序中,存放在一個Orca的DataFrame對象裏。

>>> df = orca.read_table("dfs://testRead","tb1")

將上述過程整合成的Python中可執行的腳本以下:

>>> s = orca.default_session()
>>> dfsDatabase = 'dfs://testRead'
>>> tableName = "tb1"
>>> create_partitioned_table = """
tdata=table(1..5 as id, rand(2.0,5) as value)
dbPath='{dbPath}'
if(existsDatabase(dbPath))
    dropDatabase(dbPath)
db=database(dbPath,VALUE,1..5)
tb=db.createPartitionedTable(tdata,`{tbName},`id)
tb.append!(tdata)
""".format(dbPath=dfsDatabase, tbName=tableName)
>>> s.run(create_partitioned_table)
>>> df = orca.read_table(dfsDatabase, tableName)

8.2 Orca分區表的特殊差別

在DolphinDB中,分區表與內存表存在着一些差別,在Orca中,分區表的操做也存在這諸多限制。

  • allanymedian函數

pandas和Orca的內存表進行group by以後支持調用all,anymedian函數,Orca的分區表則不支持。

  • 對非整數類型的index重複選擇

pandas和Orca的內存表支持如下操做,而Orca的分區表不支持:

>>> ps = pd.Series([0,1,2,3,4], index=['a','b','c','d','e'])
>>> os = orca.Series([0, 1, 2, 3, 4], index=['a', 'b', 'c', 'd', 'e'])
>>> ps[['a','b','a']]
# output
a    0
b    1
a    0
dtype: int64
>>> os[['a','b','a']]
# output
a    0
b    1
a    0
dtype: int64

因爲Orca的分區表實現機制的限制,許多對錶結構、表數據的修改操做對分區表都是不支持的,例如:

  • 以DataFrame的index爲基準對齊設置某一列的值

pandas和Orca的內存表能夠這樣設置一列,而Orca的分區表不支持:

>>> df = pd.DataFrame({"a": [1,2,3]}, index=[0,1,2])
>>> df
# output
a
0  1
1  2
2  3

>>> ps = pd.Series([10,20,30], index=[0,2,3])
>>> os = orca.Series([10,20,30], index=[0,2,3])
>>> os
# output
0    10
2    20
3    30
dtype: int64

>>> df["b"] = s
>>> df
# output
a     b
0  1  10.0
1  2   NaN
2  3  20.0
  • 大部分支持inplace參數的函數對Orca的分區表無效

例如rename函數:

>>> df=orca.read_table("dfs://demoDB", "tb1")
>>> df.rename(columns={"value": "values"}, inplace=True)
raise error:A segmented table is not allowed to be renamed inplace
相關文章
相關標籤/搜索