# Vector {#vector}

Vector is a container that holds a list of objects in a given order. The index of elements in a vector always starts from 0. Vectors can be modified or augmented. Data in a vector can be of different types, but the performance is optimized when all elements in a vector are of the same type. This section discusses vectors with scalar elements of the same data type \(also called "typed vectors"\). The next section [Tuple \(ANY Vector\)](TupleANYVector.md) discusses vectors with elements of different data types or with elements that are not scalars \(also called "tuples" or "ANY vectors"\).

-   **[Tuple \(ANY Vector\)](../../../../Programming/DataTypesandStructures/DataForms/Vector/TupleANYVector.md)**  

-   **[subarray](../../../../Programming/DataTypesandStructures/DataForms/Vector/subarray.md)**  

-   **[array vector](../../../../Programming/DataTypesandStructures/DataForms/Vector/arrayVector.md)**  

-   **[Big Array](../../../../Programming/DataTypesandStructures/DataForms/Vector/BigArray.md)**  

-   **[columnar tuple](../../../../Programming/DataTypesandStructures/DataForms/Vector/columnarTuple.md)**  


**Parent topic:**[Data Forms](../../../../Programming/DataTypesandStructures/DataForms/DataForms.md)

## Creating Vectors {#creating-vectors}

There are multiple ways of creating a vector:

\(1\) Space-separated elements

```
x = 3 6 1 5 9;
x;
// output: [3,6,1,5,9]
// typed vectors are always displayed within square brackets. We will see later that tuples are always displayed within round brackets.

x=10 2.5;
typestr x;
// output: FAST DOUBLE VECTOR
// note this is a DOUBLE vector, not a tuple. The system interprets 10 as a DOUBLE, not an INT.

x = 3 NULL 6 1 NULL 9;
x;
// output: [3,,6,1,,9]
typestr x;
// output: FAST INT VECTOR
```

There is a convenient way to create a STRING vector with backquotes \(\`\) if all of its elements are one word:

```
x=`IBM`MS`GOOG`YHOO`EBAY;
x;
// output: ["IBM","MS","GOOG","YHOO","EBAY"]
```

If an element of a STRING vector contain space, it must be enclosed by double quotes or single quotes.

```
x="Goldman Sachs" 'Morgan Stanley';
x;
// output: ["Goldman Sachs","Morgan Stanley"]
```

\(2\) Comma-separated elements in square brackets. It allows for line breaks before or after commas.

```
x = [3,6,1,5,9];
x;
// output: [3,6,1,5,9]
size x;
// output: 5

// define a vector across multiple lines
x = [3,6,1
,5,9]
x
// output: [3,6,1,5,9]

// compare x with the following:
y = [3 6 1 5 9];
y;
// output: ([3,6,1,5,9])
size y;
// output: 1
// since we don't use comma within the square brackets of y, y is a one-element vector.
```

\(3\) A vector from a [seq](../../../../Functions/s/seq.md).

```
x=1..10
x;
// output: [1,2,3,4,5,6,7,8,9,10]
```

\(4\) A vector from a random sequence. The example below generates a random vector with function [rand](../../../../Functions/r/rand.md).

```
x=rand(3,10);
// generate a random vector of size 10 with 0,1 and 2.
x;
// output: [0,0,2,1,1,2,1,1,2,0]

timestamp=09:30:00+rand(60,5);
timestamp;
// output: [09:30:25,09:30:00,09:30:40,09:30:19,09:30:53]

price=5.0+rand(100.0,5)
price;
// output: [32.826156,13.066499,52.872136,70.885178,104.408126]
```

\(5\) Use the [array](../../../../Functions/a/array.md).

```
x = array(int, 0);
// initialize an empty integer vector

x;
// output: []
x.append!(1..10);
// after a vector is created, its length could be extended with the append! function.
x;
// output: [1,2,3,4,5,6,7,8,9,10]
```

DolphinDB offers a "capacity" parameter in the array function. If used properly, it can enhance the performance. For details, please see [array](../../../../Functions/a/array.md) function.

\(6\) A vector from a matrix column. For example, the first column of matrix m:

```
m=1..6$2:3;
m;
```

|\#0|\#1|\#2|
|---|---|---|
|1|3|5|
|2|4|6|

```
m[0];
// output: [1,2]
```

\(7\) A vector from a table column. For example, trades.qty indicates column qty from table trades.

```
trades=table(`A`B`C as sym, 100 200 300 as qty);
trades.qty;

// output: [100, 200, 300]
```

### Creating Vectors of SYMBOL Type {#section_tcq_j2y_jxb .section}

\(1\) With function [array](../../../../Functions/a/array.md)

``` {#codeblock_p3p_mry_jxb}
syms=array(SYMBOL, 0, 100);
// create an empty symbol array;

typestr syms;
// output: FAST SYMBOL VECTOR
syms.append!(`IBM`C`MS);
syms;
// output: ["IBM","C","MS"]
```

\(2\) With type conversion

``` {#codeblock_cq3_wsy_jxb}
syms=`IBM`C`MS;
typestr syms;
// output: STRING VECTOR

// converting to a symbol vector;
sym=syms$SYMBOL;

typestr sym;
// output: FAST SYMBOL VECTOR

typestr syms;
// output: STRING VECTOR
```

\(3\) With function [rand](../../../../Functions/r/rand.md)

``` {#codeblock_fh3_bty_jxb}
syms=`IBM`C`MS;
symRand=rand(syms, 10);
//generate a random SYMBOL vector

symRand;
// output: ["IBM","IBM","IBM","MS","C","C","MS","IBM","C","MS"]
typestr symRand;
// output: FAST SYMBOL VECTOR
```

**Note**: The `rand` function takes a string vector and generates a symbol vector. The `rand` function doesn't change any other input data types. We intentionally make this exception as when users generate a random vector based on a string vector, in most cases they would like to get a symbol vector.

## Accessing Vectors {#accessing-vectors}

We can access a vector with X\[Y\], where Y can be an integer, a boolean vector, an integer vector or a pair.

-   Accessing a vector by position. To access the i-th element in vector X, use X\[i\]. i starts from 0.


```
x=3 6 1 5 9;
x[1];
// output: 6
```

-   Accessing a sub sequence of a vector with boolean indexing or boolean expression. The boolean indexing vector should have the same size as the original vector.


```
x=3 6 1 5 9;
y= true false true false false;
x[y];
// output: [3,1]

x[x>3];
// output: [6,5,9]

x[x%3==0];
// output: [3,6,9]
```

-   Accessing a sub sequence of vector X with an indexing vector, which contains the indexes of the values being retained.


```
x=3 6 1 5 9;
y=4 0 2;
x[y];
// output: [9,3,1]
```

-   Accessing a sub sequence of vector X with a pair in the format of X\[a:b\], where 0&lt;=a, b&lt;=size\(X\). This indexing is upper bound exclusive.


```
x=3 6 1 5 9;
x[1:3];
// output: [6,1]

x[3:1];
// output: [1,6]
// in reverse order

x[1:];
// output: [6,1,5,9]
// accessing the vector elements staring from position 1

x[:3];
// output: [3,6,1]
// accessing the first 3 elements

x[:];
// output: [3,6,1,5,9]
// accessing all elements of x
```

Function [size](../../../../Functions/s/size.md) returns the number of elements of a vector, while [count](../../../../Functions/c/count.md) returns the number of non-null elements.

```
x=3 6 NULL 5 9;
size x;
// output: 5
count x;
// output: 4
```

## Modifying Vectors {#modifying-vectors}

The elements of a vector can be modified. Appending new elements to a vector is also permitted. However, it is not allowed to delete or insert elements at any position except the last position. To delete the last element, use the function [pop!](../../../../Functions/p/pop!.md).

```
x = 3 6 1 5 9;

x[1]=4;
x;
// output: [3,4,1,5,9]

x.append!(10 11 12);
// output: [3,4,1,5,9,10,11,12]
x;
// output: [3,4,1,5,9,10,11,12]

x.pop!();
// output: 12
x;
// output: [3,4,1,5,9,10,11]
```

A new copy of x is assigned to y with statement y=x. As a result, statement "y=x; y\[i\]=a;" does not change vector x. This is different from Python.

```
x = 3 6 1 5 9;
y=x;
y;
// output: [3,6,1,5,9]

y[1]=5;
y;
// output: [3,5,1,5,9]

x;
// output: [3,6,1,5,9]
```

If we use &amp;y=x, both x and y point to the same object. Modifying either x or y will update the other.

```
x = 3 6;
&y=x;
y;
// output: [3,6]

y[1]=5;
x;
// output: [3,5]

x[0]=6;
y;
// output: [6,5]
```

Replacing a sub vector through statement: x\[begin:end\] = a vector or a scalar; note that the upper bound is exclusive.

```
x = 3 4 1 5 9;
x[3:5]=7..8;
x;
// output: [3,4,1,7,8]

x[2:]=1;
x;
// output: [3,4,1,1,1]

x[:]=2;
x;
// output: [2,2,2,2,2]
```

Replacing a sub vector with a boolean expression: x\[boolean expression\] = y

```
x=`IBM`MS`GOOG`YHOO`EBAY;
x[x==`MS]=`GS
x;
// output: ["IBM","GS","GOOG","YHOO","EBAY"]

x=1..10;
x[x%3==0]=99;
x;
// output: [1,2,99,4,5,99,7,8,99,10]

x=6 4 2 0 2 4 6;
x[x>3];
// output: [6,4,4,6]

shares=500 1000 1000 600 2000;
prices=25.5 97.5 19.2 38.4 101.5;
prices[shares>800];
// output: [97.5,19.2,101.5]
```

## Appending a vector with different data types {#appending-a-vector-with-different-data-types}

What happens if we append typed vectors with data of different types? This operation can be successful only if the new elements can be converted to the vector's data type. Otherwise, this operation fails. For example, we cannot append an INT vector with a STRING.

```
// append an INT vector with STRING
x=1 2 3;
typestr x;
// output: FAST INT VECTOR
x.append!(`orange);
// output: Incompatible type. Expected: INT, Actual: STRING

// append an INT vector with DOUBLE
x.append!(4.3);
// output: [1,2,3,4]
typestr x;
// output: FAST INT VECTOR

// append an INT vector with BOOL
x.append!(false);
// output: [1,2,3,4,0]
typestr x;
// output: FAST INT VECTOR

// append a STRING vector with INT
x=`C `GS `MS;
x.append!(4);
// output: ["C","GS","MS","4"]
x[3];
// output: 4
typestr x[3];
// output: STRING
```

## Manipulating Vectors {#manipulating-vectors}

Function [reverse](../../../../Functions/r/reverse.md) returns a new vector in the reverse order.

```
x=1..10;
y=reverse x;
y;
// output: [10,9,8,7,6,5,4,3,2,1]
x;
// output: [1,2,3,4,5,6,7,8,9,10]
```

Function [shuffle](../../../../Functions/s/shuffle.md) returns a new vector that randomly reorganize the order of the elements of the original vector.

```
x=1..10;
shuffle x;
// output: [9,2,10,3,1,6,8,4,5,7]
x;
// output: [1,2,3,4,5,6,7,8,9,10]
```

Function [shuffle!\(\)](../../../../Functions/s/shuffle!.md) changes the input variable by randomly reorganizing the order of its elements.

```
x=1..10;
shuffle!(x);
// output: [8,10,1,3,2,4,7,5,6,9]
x;
// output: [8,10,1,3,2,4,7,5,6,9]
```

Function [join](../../../../Functions/j/join.md) concatenates two vectors and returns a new vector.

```
x=1..3;
y=4..6;
z=join(x, y);
z;
// output: [1,2,3,4,5,6]
x join y join y;
// output: [1,2,3,4,5,6,4,5,6]
```

Function [cut\(X, a\)](../../../../Functions/c/cut.md) divides a vector into sub vectors, where a is the size of the sub vectors. To merge a list of vectors, use function [flatten](../../../../Functions/f/flatten.md).

```
x=1..10;
x cut 2;
// output a tuple: ([1,2],[3,4],[5,6],[7,8],[9,10])

x cut 3;
// output: ([1,2,3],[4,5,6],[7,8,9],[10])   
// the remaining element "10" forms an vector.

x cut 5;
// output: ([1,2,3,4,5],[6,7,8,9,10])

x cut 9;
// output: ([1,2,3,4,5,6,7,8,9],[10])

flatten (x cut 9);
// output: [1,2,3,4,5,6,7,8,9,10]
```

Function [take\(X, n\)](../../../../Functions/t/take.md) takes n elements from vector X starting with the first element. If n is larger than the size of X, it restarts from the first element.

```
x=3 6 1 5 9;
x take 3;
// output: [3,6,1]
take(x,12);
// output: [3,6,1,5,9,3,6,1,5,9,3,6]
```

The following 3 functions make it very convenient to deal with lead-lag relations in time series analysis.

[prev\(X\)](../../../../Functions/p/prev.md): move all elements of a vector one position to the right

[next\(X\)](../../../../Functions/n/next.md): move all elements of a vector one position to the left

[move\(X,a\)](../../../../Functions/m/move.md): move all elements of a vector k positions to the right when k is a positive integer; move -k positions to the left when k is a negative integer.

```
x=3 6 1 5 9;
y=prev x;
y;
// output: [,3,6,1,5]
z = next x;
z;
// output: [6,1,5,9,]

v=x move 2;
v;
// output: [,,3,6,1]
x move -2;
// output: [1,5,9,,]
```

## Searching in Vectors {#searching-in-vectors}

For each element in X, function [in\(X,Y\)](../../../../Functions/i/in.md) checks whether it exists in vector Y.

```
x = 4 5 16;
y = 3 6 1 5 9 4 19 31 2 8 7 2;
x in y;
// output: [1,1,0]
// both 4 and 5 are in y; 16 is not in y;

in(x,y);
// output: [1,1,0]
```

Function [at](../../../../Functions/a/at.md) returns the positions of elements of vector X that meet certain conditions.

```
x=1 2 3 2 1;
at(x==2);
// output: [1,3]

at(x>2);
// output: [2]
```

Function [find\(X, Y\)](../../../../Functions/f/find.md) returns the position\(s\) of the first occurrence\(s\) of each element of Y in vector X, where Y could be a scalar or vector. If an element in Y does not exist in X, the function returns -1.

```
x = 8 6 4 2 0 2 4 6 8;
find(x,2);
// output: 3

y= 6 0 7;
x find y;
// output: [1,4,-1]
```

When searching in a large vector for elements in another large vector with function find, the system would build a dictionary to optimize the performance. However, when searching a couple of values against a large vector, the system would not construct a dictionary to optimize the performance. Whether to build a dictionary or not in searching is dynamically determined. If we already have a sorted vector and we only need to search a small amount of data, [binsrch](../../../../Functions/b/binsrch.md) is a better fit, as building dictionaries for super large data sets can take a significant amount of time and memory.

Function [binsrch\(X, Y\)](../../../../Functions/b/binsrch.md) returns the index\(es\) of the first occurrences of the elements of Y in vector X, where Y could be a scalar or vector. X has to be sorted in an ascending order. If an element in Y is not in X, then it returns -1.

```
x = 1..10;
x binsrch 2;
// output: 1
y= 4 5 12;
x binsrch y;
// output: [3,4,-1]
```

Function [searchK\(X, a\)](../../../../Functions/s/searchK.md) returns the value at the k-th smallest position in vector X, where X must be a vector and a must be a scalar. Sorting is not required for vector X.

```
x=9 9 6 6 6 3 0 0;
searchK(x,1);
// output: 0
searchK(x,2);
// output: 0
searchK(x,3);
// output: 3
searchK(x,4);
// output: 6
searchK(x,5);
// output: 6
searchK(x,6);
// output: 6
searchK(x,7);
// output: 9
```

When we calculate price to earnings ratios of stocks at a certain date, we use earnings that was announced most recently, not earnings announced on that date as corporate earnings are only announced 4 times in a year. In such situations, the asof function comes in handy.

Assume a vector X has been sorted in ascending order. For each element y of Y, function [asof\(X, Y\)](../../../../Functions/a/asof.md) returns the index of the last element in X that is no greater than y. In practice, both X and Y are often temporal types. Also see "asof-join".

```
// data about phone number changes
x=[2005.12.01, 2007.03.15, 2010.12.24, 2013.08.31];
y="(201) 1234-5678" "(212) 8467-5523" "(312) 1258-6679" "(212) 4544-8888";

// get the phone number on date 2005.12.01 and 2010.12.25
y[asof(x, [2005.12.01,2010.12.25])];
// output: ["(201) 1234-5678","(312) 1258-6679"]
```

## Sorting elements in Vectors {#sorting-elements-in-vectors}

Function [sort\(X, \[boolean\]\)](../../../../Functions/s/sort.md) sorts the values of a vector. It returns a new sorted vector.

```
x = 3 6 1 5 9;
y = sort x;
y;
// output: [1,3,5,6,9]
y = sort(x, false);
// sort x in descending order
y;
// output: [9,6,5,3,1]
```

Function [isort\(X, \[boolean\]\)](../../../../Functions/i/isort.md) returns the indexes of the elements of sort\(X\) in X. X\[isort X\] is equivalent to sort\(X\).

```
isort x;
// output: [2,0,3,1,4]
// 2 0 3 1 4 are the indexes of 1 3 5 6 9 in x

isort(x, false);
// output: [4,1,3,0,2]

x[isort x];
// output: [1,3,5,6,9]
```

In contrast,[rank\(X, \[boolean\]\)](../../../../Functions/r/rank.md) returns the indexes of the elements of X in sort\(X\).

```
rank x;
// output: [1,3,0,2,4]

rank(x, false);
// output: [3,1,4,2,0]
```

Function [sort!](../../../../Functions/s/sort!.md) produces an in-place sort.

```
x= 3 6 1 5 9;
sort!(x);
// output: [1,3,5,6,9]
x;
// output: [1,3,5,6,9]
```

## Using Vectors with Operators {#using-vectors-with-operators}

All operators can take vectors as input arguments. For more examples and details, please refer to [Operators](../../../Operators/Operators.md) and [Function References](../../../../Functions/chap_function_references.md).

```
x = 1 2 3;
y = 4 5 6;

x * y;
// output: [4,10,18]

x / y;
// output: [0,0,0]
// when both x and y are integers, "/" means integer division, which is equivalent to applying floor function after division.

x \ y;
// output: [0.25,0.4,0.5]

3 * x;
// output: [3,6,9]

x ** y;
// output: 32
// inner product: 1*4 + 2*5 + 3*6
```

In most scenarios, operations with NULL operand produce null value. But there are exceptions. Please see [Null Value Operations](../../../DataManipulation/NullValueManipulation/NullValueOperation/NullValueOperation.md) for details.

```
x = 3 NULL 1 NULL 9;
y = 4 5 2 3 NULL;
x+y;
// output: [7,,3,,]
x>0;
// output: [1,0,1,0,1]
```

## Using Vectors in Functions {#using-vectors-in-functions}

The following are examples of applying functions to vectors. For details, please refer to [Function References](../../../../Functions/chap_function_references.md).

```
x= 3 6 1 5 9;

avg x;
// output: 4.8

med x;
// output: 5

sum x;
// output: 24

std x;
// output: 3.03315

log x;
// output: [1.098612,1.791759,0,1.609438,2.197225]

exp x;
// output: [20.085537,403.428793,2.718282,148.413159,8103.083928]

x pow 2;
// output: [9,36,1,25,81]

x = 1 2 3;
y = 1 2 2;
x wavg y;
// output: 2.2
// calculate weighted average for vector x: (1*1+2*2+3*2)/(1+2+2)

x = 3 NULL NULL NULL 9;
avg x;
// output: 6
// calculate the average of vector x, ignoring null values.

y = 1 2 3 4 5;
x wavg y;
// output: 8
```

## Vector of functions {#vector-of-functions}

Vectors can be the container for a list of functions. This is especially useful when running the same inputs through multiple functions that return the same types of data.

```
x=[3.1, 4.5, 6];
desp=[std, avg, sum, median, max, min];
desp(x);
// output: [1.450287,4.533333,13.6,4.5,6,3.1]

// use both element-wise and aggregation functions at the same time.
desp=[log, std, avg, sum, median, max, min];
desp(x);
```

|log|std|avg|sum|med|max|min|
|---|---|---|---|---|---|---|
|1.131402|1.450287|4.533333|13.6|4.5|6|3.1|
|1.504077|1.450287|4.533333|13.6|4.5|6|3.1|
|1.791759|1.450287|4.533333|13.6|4.5|6|3.1|

