因爲DolphinDB是一款相對成熟的高性能分佈式時序數據庫,其底層對一些方法的處理機制已經成型,這就決定了Orca在某些細節方面會與pandas存在差別。爲了方便用戶更快地瞭解和掌握Orca,本文按照如下幾個模塊來系統地介紹Orca與pandas存在的差別。html
1 數據類型的差別python
2 通用函數的差別git
Orca提供如下通用函數:github
connect
:將會話鏈接到DolphinDB服務器merge
: 鏈接兩個DataFrameconcat
:按照columns對齊鏈接兩個DataFramedate_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_csv
和read_table
。
3.1 read_csv
函數
下面詳細介紹Orca的read_csv
函數與pandas的read_csv
函數的差別。
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)
在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})
pandas的這兩個參數支持對正則表達式的解析,而Orca的目前沒法支持這一點。
bool類型,該參數爲True時,表示容許分區方式將數據導入(其實是調用DolphinDB的ploadText函數);當該參數爲False時,表示強制以非分區的方式導入數據(其實是調用DolphinDB的loadText函數)。
注意:Orca的分區表與Orca的內存表相比,在操做時也存在許多差別,具體見第8節Orca分區表的特殊差別。若您的數據量不是很大,且在使用Orca時對Orca與pandas的一致性要求更高,請儘可能不要將數據以分區的方式導入。若您數據量極大,對性能要求極高,則建議您採用分區方式導入數據。
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的建立與修改
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
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
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官方提供的Series和DataFrame的文檔,依次介紹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
:遍歷DataFrameiteritems
:遍歷DataFramelookup
:根據標籤查詢數據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
loc
與iloc
修改Series和DataFrame中值的類型pandas能夠經過loc
和iloc
更改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
loc
與iloc
修改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
loc
和iloc
暫不支持對MultiIndex的訪問4.3.4 Binary operator functions
除了combine和combine_first函數以外,Orca支持pandas提供的全部二元函數。可是,Orca的DataFrame或者Series在進行四則運算時,除了本文第2.2小節所說起的差別以外,在四則運算進行的方式上也存在必定差別。
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
:分組運算rollin
g:滑動窗口ewm
:指數加成滑動下面介紹一下Orca與pandas仍存在的差別。
apply
,agg
,aggregate
函數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提供的函數中,有如下差別。
cummax
, cummin
, cumprod
和cumsum
函數這幾個函數在遇到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取值爲True時,最小的排名爲0,不然最小的排名爲1,和pandas一致。
表示排名的分組數,參考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
:重置indexreset_index
:重置indexset_index
:設置index4.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
函數,該函數目前支持的參數以下:
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分區表的概念。
在下列狀況下,數據將以分區表的形式處理:
在本文第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中,分區表的操做也存在這諸多限制。
all
,any
和median
函數pandas和Orca的內存表進行group by以後支持調用all
,any
和median
函數,Orca的分區表則不支持。
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的分區表實現機制的限制,許多對錶結構、表數據的修改操做對分區表都是不支持的,例如:
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
例如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