array vector

In DolphinDB, an array vector is a two-dimensional vector where each row is a variable-length vector. With array vectors, multiple columns with the same data type, such as columns of a stock’s best ask prices, can be stored in one single column. This can significantly reduce the complexity of some common queries and calculations. If there are a lot of duplicate data in multiple columns, it is also recommended to use an array vector to store these data as it improves data compression ratio and improves query performance.

Binary operations can be performed between an array vector and a scalar, a vector or another array vector.

Currently, array vectors can only be used in in-memory tables and DFS tables created with the TSDB storage engine. The OLAP storage engine does not support array vectors. Also, columns holding array vectors cannot be specified as the partitioning columns or sort columns (TSDB engine) of a partitioned table.

Creating an Array Vector

Use functions array or bigarray to initialize an empty array vector. When specifying the parameter dataType, append a pair of square brackets (“[]“) to the data type to indicate the creation of an array vector, for example, INT[]. The parameter initialSize must be 0.

Note that only the following data type categories are allowed: Logical, Integral (excluding INT128 and COMPRESS), Floating, DECIMAL, Temporal.

Conversion between Vectors and Array Vectors

  • From vectors to array vectors

(1) Use arrayVector to convert a vector to an array vector.

(2) Use fixedLengthArrayVector to combine multiple vectors into one array vector.

  • From array vectors to vectors:

Use flatten to convert an array vector to a vector.

$ a=array(INT[], 0, 10).append!([1 2 3, 4 5, 6 7 8, 9 10]);
$ a
[[1,2,3],[4,5],[6,7,8],[9,10]]

$ flatten(a)
[1,2,3,4,5,6,7,8,9,10]

Convert an Array Vectors into a matrix

Use function matrix to convert array vectors with each element of same length into matrices for further calculations.

$ bid = array(DOUBLE[], 0, 20).append!([1.4799 1.479 1.4787 1.4784 1.4667, 1.4796 1.479 1.4782 1.4781 1.4783, 1.4791 1.479 1.4785 1.4698 1.4720, 1.4699 1.469 1.4707 1.4704 1.4697, 1.4789 1.477 1.4780 1.4724 1.4669])
$ ask = array(DOUBLE[], 0, 20).append!([1.4821 1.4825 1.4828 1.4900 1.4792, 1.4818 1.482 1.4821 1.4818 1.4829, 1.4814 1.4818 1.482 1.4825 1.4823, 1.4891 1.4885 1.4898 1.4901 1.4799, 1.4811 1.4815 1.4818 1.4800 1.4799])

$ TradeDate = 2022.01.01 + 1..5
$ SecurityID = rand(`APPL`AMZN`IBM, 5)
$ t = table(SecurityID as `sid, TradeDate as `date, bid as `bid, ask as `ask)
$ result = select toArray(matrix(bid).corrMatrix()) as corr_bid,  toArray(matrix(ask).corrMatrix()) as corr_ask from t group by sid
$ corrMatrix_bid = result.corr_bid.matrix().avg().reshape(5:5)
$ corrMatrix_ask = result.corr_ask.matrix().avg().reshape(5:5)
$ corrMatrix_bid;

col1

col2

col3

col4

col5

1

0.9995

0.9984

0.7417

(0.1308)

0.9995

1

0.9997

0.7214

(0.1466)

0.9984

0.9997

1

0.7061

(0.1589)

0.7417

0.7214

0.7061

1

(0.0264)

(0.1308)

(0.1466)

(0.1589)

(0.0264)

1

$ corrMatrix_ask;

col1

col2

col3

col4

col5

1

0.9999

0.9997

0.9963

(0.9861)

0.9999

1

0.9999

0.9974

(0.9883)

0.9997

0.9999

1

0.9981

(0.9899)

0.9963

0.9974

0.9981

1

(0.9968)

(0.9861)

(0.9883)

(0.9899)

(0.9968)

1

Appending Data to an Array Vector

Use append! to append scalar, vector or array vector to an array vector. Updates and deletes are currently not supported for array vectors.

// append a scalar
$ a=array(DOUBLE[], 0, 10).append!(2.5);
$ print a;
[[2.5]]]

// append a tuple
$ a=array(DATE[], 0, 10).append!((2021.10.15, 2021.10.16, 2021.10.17));
$ print a;
[[2021.10.15],[2021.10.16],[2021.10.17]]

// append an array vector
$ a=array(INT[], 0, 10).append!([1 2 3, 4 5, 6 7 8, 9 10]);
$ print a;
[[1,2,3],[4,5],[6,7,8],[9,10]]

Retrieving Data from Array Vectors

  • Array Vector

$ av =array(DOUBLE[], 0, 10).append!([1.0, 2.1 4.1 6.8, 0.5 2.2 2]);
$ print av
[[1],[2.1,4.1,6.8],[0.5,2.2,2]]
$ typestr(av)
FAST DOUBLE[] VECTOR
  • Tuple

$ tp = [[1],[2.1,4.1,6.8],[0.5,2.2,2]]
$ typestr(tp)
ANY VECTOR

Despite some similarities, the way data is retrieved from a tuple and from an array vector is different.

Similarities:

You can use the row function to retrieve rows from both an array vector and a tuple.

Differences:

Array vectors only have column index. Therefore, to identify a column in the array vector, use av[index] where the index starts from 0. To identify a row in the array vector, we must use the row function via av.row(index).

To retrieve an individual element from a row in the array vector, first identify the column then the row via av[indexe1][index2]; or first identify the row then the column via av.row(index1)[index2].

$ av[1]
[,4.1,2.2]

$ tp[,1]
(,4.1,2.2)

$ av.row(1)
[2.1,4.1,6.8]

$ tp[1]
[2.1,4.1,6.8]

Importing Columns as Array Vectors (2.00.4 and later versions)

Currently, DolphinDB doesn’t support importing multiple columns from a text file into a single column. To import array vectors, combine the associated columns into one and separate the values in each row with a user-specified delimiter in the text file. For example, combine the 5 best ask prices (populated in 5 columns) into one column by “1.4799|1.479|1.4787|1.4796|1.479”.

When using loadText (ploadText) or loadTextEx to import data, specify the parameter arrayDelimiter (which is “|” in the above example) to separate the values in the column holding the array vector, so the values in the column can be recognized as array vector during the import.

Note: Before the import, use the schema parameter to update the data type of the columns holding the array vectors with the corresponding array vector data type.

$ bid = array(DOUBLE[], 0, 20).append!([1.4799 1.479 1.4787, 1.4796 1.479 1.4784, 1.4791 1.479 1.4784])
$ ask = array(DOUBLE[], 0, 20).append!([1.4821 1.4825 1.4828, 1.4818 1.482 1.4821, 1.4814 1.4818 1.482])
$ TradeDate = 2022.01.01 + 1..3
$ SecurityID = rand(`APPL`AMZN`IBM, 3)
$ t = table(SecurityID as `sid, TradeDate as `date, bid as `bid, ask as `ask)
$ t;
$ saveText(t,filename="D:/t.csv",delimiter=',',append=true)
$ path = "D:/t.csv"
$ schema=extractTextSchema(path);
$ update schema set type = "DOUBLE[]" where name="bid" or name ="ask"
$ t = loadText(path, schema=schema, arrayDelimiter=",")
$ t;

sid

date

bid

ask

AMZN

2022.01.02

[1.4799,1.479,1.4787]

[1.4821,1.4825,1.4828]

AMZN

2022.01.03

[1.4796,1.479,1.4784]

[1.4818,1.482,1.4821]

IBM

2022.01.04

[1.4791,1.479,1.4784]

[1.4814,1.4818,1.482]

Combining Columns into an Array Vector

Use fixedLengthArrayVector to store multiple columns from a table as a single column.

$ syms="A"+string(1..30)
$ datetimes=2019.01.01T00:00:00..2019.01.31T23:59:59
$ n=200
$ if(existsDatabase("dfs://stock")) {
$ dropDatabase("dfs://stock")
$ }
$ db=database("dfs://stock",RANGE,cutPoints(syms,3));
$ t=table(take(datetimes,n) as trade_time, take(syms,n) as sym,take(500+rand(10.0,n), n) as bid1, take(500+rand(20.0,n),n) as bid2)
$ quotes=db.createPartitionedTable(t,`quotes,`sym).append!(t)
$ t1=select sym, fixedLengthArrayVector(bid1,bid2) as bid from quotes

Concatenating Grouped Values into an Array Vector

The toArray function is used in conjunction with the group by clause in a SQL query. toArray concatenates the values in each group to create a row of the array vector, so the values of each group can be presented in one row.

$ ticker = `AAPL`IBM`IBM`AAPL`AMZN`AAPL`AMZN`IBM`AMZN
$ volume = 106 115 121 90 130 150 145 123 155;
$ t = table(ticker, volume);
$ t;

$ t1 = select toArray(volume) as volume_all from t group by ticker;
$ t1;

ticker

volume_all

AAPL

[106,90,150]

AMZN

[130,145,155]

IBM

[115,121,123]

Applying Row-Based Functions on Array Vectors

(1)Aggregate calculation

Support row-based functions, such as rowMax, rowStd , etc.

Support higher-order function byRow.

$ a=array(DOUBLE[], 0, 10).append!([8.3 1.2 5.6, 1.8 3.3, 0.1 2.4 6.8]);
$ rowMax(a);
[8.3, 3.3, 6.7]


$ bid = array(DOUBLE[], 0, 20).append!([1.4799 1.479 1.4787, 1.4796 1.479 1.4784, 1.4791 1.479 1.4784])
$ ask = array(DOUBLE[], 0, 20).append!([1.4821 1.4825 1.4828, 1.4818 1.482 1.4821, 1.4814 1.4818 1.482])
$ TradeDate = 2022.01.01 + 1..3
$ SecurityID = rand(`APPL`AMZN`IBM, 3)
$ t = table(SecurityID as `sid, TradeDate as `date, bid as `bid, ask as `ask)
$ t;

sid

date

bid

ask

IBM

2022.01.02

[1.4799,1.479,1.4787]

[1.4821,1.4825,1.4828]

APPL

2022.01.03

[1.4796,1.479,1.4784]

[1.4818,1.482,1.4821]

APPL

2022.01.04

[1.4791,1.479,1.4784]

[1.4814,1.4818,1.482]

$ select SecurityID, TradeDate, bid, ask,  rowAvg(bid) as bid_avg, rowAvg(ask) as ask_avg from t

SecurityID

TradeDate

bid

ask

bid_avg

ask_avg

IBM

2022.01.02

[1.4799,1.479,1.4787]

[1.4821,1.4825,1.4828]

1.4792

1.4825

APPL

2022.01.03

[1.4796,1.479,1.4784]

[1.4818,1.482,1.4821]

1.479

1.482

APPL

2022.01.04

[1.4791,1.479,1.4784]

[1.4814,1.4818,1.482]

1.4788

1.4817

  1. Window functions (moving window, cumulative window, etc.)

Use the higher-order function byRow to perform window functions on an array vector.

$ select SecurityID, TradeDate, bid, ask, byRow(cumavg, bid) as bid_cum, byRow(cumavg, ask) as ask_cum from t

SecurityID

TradeDate

bid

ask

bid_cum

ask_cum

IBM

2022.01.02

[1.4799,1.479,1.4787]

[1.4821,1.4825,1.4828]

[1.4799,1.47945,1.4792]

[1.4821,1.4823,1.482467]

APPL

2022.01.03

[1.4796,1.479,1.4784]

[1.4818,1.482,1.4821]

[1.4796,1.4793,1.479]

[1.4818,1.4819,1.481967]

APPL

2022.01.04

[1.4791,1.479,1.4784]

[1.4814,1.4818,1.482]

[1.4791,1.47905,1.478833]

[1.4814,1.4816,1.481733]