Quickstart Guide

This quickstart guide provides first time users with essential instructions for using the KDB-X library.

Prerequisites

Before you start, make sure to:

1. Import KDB-X

To access KDB-X, import it within your Python code using the following syntax:

Python

Copy
>>> import pykx as kx

Information

The use of the shortened name kx is optional and provides a terse convention for interacting with methods and objects from the KDB-X library.

2. Generate KDB-X objects

You can generate KDB-X objects in three ways. Click on a drop-down below and follow the instructions:

Use KDB-X functions

From Python data types

Execute q code

Generate KDB-X objects using pykx helper functions.

Python

Copy
>>> kx.random.random([3, 4], 10.0)
pykx.List(pykx.q('
4.976492 4.087545 4.49731   0.1392076
7.148779 1.946509 0.9059026 6.203014
9.326316 2.747066 0.5752516 2.560658
'))
>>> kx.Table(data = {'x': kx.random.random(10, 10.0), 'x1': kx.random.random(10, ['a', 'b', 'c'])})
pykx.Table(pykx.q('
x         x1
------------
0.8123546 a
9.367503  a
2.782122  c
2.392341  a
1.508133  b
'))   
                    

Generate KDB-X objects from Python, NumPy, Pandas and PyArrow objects by using the kx.toq method.

Python

Copy
>>> qlist = kx.toq(pylist)
    >>> qlist
    pykx.LongVector(pykx.q('10 20 30'))

    >>> import numpy as np
    >>> nplist = np.arange(0, 10, 2)
    >>> qlist = kx.toq(nplist)
    >>> qlist
    pykx.LongVector(pykx.q('0 2 4 6 8'))

    >>> import pandas as pd
    >>> df = pd.DataFrame({'col1': [1, 2], 'col2': [3, 4]})
    >>> df
    col1  col2
    0     1     3
    1     2     4
    >>> qtable = kx.toq(df)
    pykx.Table(pykx.q('
    col1 col2
    ---------
    1    3
    2    4
    '))

    >>> import pyarrow as pa
    >>> patab = pa.Table.from_pandas(df)
    >>> patab
    pyarrow.Table
    col1: int64
    col2: int64
    >>> qtable = kx.toq(patab)
    >>> qtable
    pykx.Table(pykx.q('
    col1 col2
    ---------
    1    3
    2    4
    '))

Generate PyKX objects using q by calling #!python kx.q:

Python

Copy
 >>> kx.q('10 20 30')
        pykx.LongVector(pykx.q('10 20 30'))

        >>> kx.q('([]5?1f;5?`4;5?0Ng)')
        pykx.Table(pykx.q('
        x         x1   x2
        ---------------------------------------------------
        0.439081  ncej 8c6b8b64-6815-6084-0a3e-178401251b68
        0.5759051 jogn 5ae7962d-49f2-404d-5aec-f7c8abbae288
        0.5919004 ciha 5a580fb6-656b-5e69-d445-417ebfe71994
        0.8481567 hkpb ddb87915-b672-2c32-a6cf-296061671e9d
        0.389056  aeaj 580d8c87-e557-0db1-3a19-cb3a44d623b1
        '))

3. Interact with KDB-X objects

You can interact with KDB-X objects in a variety of ways, for example, through indexing using Pythonic syntax, passing PyKX objects to q/NumPy functions, querying via SQL/qSQL syntax or by using the q functionality via the context interface.

For now, we recommend a few examples:

  • Create a KDB-X list and interact with it using indexing and slices:

    Python

    Copy
    >>> qarray = kx.random.random(10, 1.0)
    >>> qarray
    pykx.FloatVector(pykx.q('0.391543 0.08123546 0.9367503 0.2782122 0.2392341 0.1508133 0.1567317 0.9785 ..'))
    >>> qarray[1]
    pykx.FloatAtom(pykx.q('0.08123546'))
    >>> qarray[1:4]
    pykx.FloatVector(pykx.q('0.08123546 0.9367503 0.2782122'))
  • Assign objects to KDB-X lists:

    Python

    Copy
    >>> qarray = kx.random.random(3, 10.0, seed=10)
    pykx.FloatVector(pykx.q('0.891041 8.345194 3.621949'))
    >>> qarray[1] = 0.1
    >>> qarray
    pykx.FloatVector(pykx.q('0.891041 0.1 3.621949'))
  • Create a KDB-X table and manipulate using Pythonic syntax:

    Python

    Copy
    >>> N = 100
    >>> qtable = kx.Table(
        data={
            'x': kx.random.random(N, 1.0),
            'x1': 5 * kx.random.random(N, 1.0),
            'x2': kx.random.random(N, ['a', 'b', 'c'])
        }
    )
    >>> qtable
    pykx.Table(pykx.q('
    x         x1         x2
    -----------------------
    0.3550381 1.185644   c
    0.3615143 2.835405   a
    0.9089531 2.134588   b
    0.2062569 3.852387   a
    0.481821  0.07970141 a
    0.2065625 1.786519   a
    0.5229178 0.1273692  c
    0.3338806 3.440445   c
    0.414621  3.188777   c
    0.9725813 0.1922818  b
    0.5422726 4.486179   b
    0.6116582 3.967756   a
    0.3414991 1.018642   b
    0.9516746 3.878809   c
    0.1169475 0.3469163  c
    0.8158957 2.050957   a
    0.6091539 1.168774   a
    0.9830794 3.562923   b
    0.7543122 0.6961287  a
    0.3813679 1.350938   b
    ..
    '))
    >>> qtable[['x', 'x1']]
    pykx.List(pykx.q('
    0.3550381 0.3615143 0.9089531 0.2062569 0.481821   0.2065625 0.5229178 0.3338..
    1.185644  2.835405  2.134588  3.852387  0.07970141 1.786519  0.1273692 3.4404..
    '))
    >>> qtable[0:5]
    pykx.Table(pykx.q('
    x         x1         x2
    -----------------------
    0.3550381 1.185644   c
    0.3615143 2.835405   a
    0.9089531 2.134588   b
    0.2062569 3.852387   a
    0.481821  0.07970141 a
    '))
  • Pass a KDB-X object to a q function:

    Python

    Copy
    >>> qfunction = kx.q('{x+til 10}')
    >>> qfunction(kx.toq([random() for _ in range(10)], kx.FloatVector))
    pykx.FloatVector(pykx.q('0.3992327 1.726329 2.488636 3.653597 4.028107 5.444905 6.542917 7.00628 8.152..'))
  • Apply a Python function on a KDB-X Vector:

    Python

    Copy
    >>> qvec = kx.random.random(10, 10, seed=42)
    >>> qvec
    pykx.LongVector(pykx.q('4 7 2 2 9 4 2 0 8 0'))
    >>> qvec.apply(lambda x:x+1)
    pykx.LongVector(pykx.q('5 8 3 3 10 5 3 1 9 1'))
  • Pass KDB-X arrays of objects to Numpy functions:

    Python

    Copy
    >>> qarray1 = kx.random.random(10, 1.0)
    >>> qarray1
    pykx.FloatVector(pykx.q('0.7880561 0.9677446 0.9325539 0.6501981 0.4837422 0.5338642 0.5156039 0.31358..'))
    >>> qarray2 = kx.random.random(10, 1.0)
    >>> qarray2
    pykx.FloatVector(pykx.q('0.04164985 0.6417901 0.1608836 0.691249 0.4832847 0.6339534 0.4614883 0.06373..'))

    >>> np.max(qarray1)
    0.9677445779088885
    >>> np.sum(kx.random.random(10, 10))
    43
    >>> np.add(qarray1, qarray2)
    pykx.FloatVector(pykx.q('0.8297059 1.609535 1.093438 1.341447 0.9670269 1.167818 0.9770923 0.3773123 1..'))
  • Query using SQL/qSQL:

    SQL

    Copy
    >>> N = 100
    >>> qtable = kx.Table(
        data={
            'x': kx.random.random(N, ['a', 'b', 'c'],
            'x1': kx.random.random(N, 1.0),
            'x2': 5 * kx.random.random(N, 1.0),
        }
    )
    >>> qtable[0:5]
    pykx.Table(pykx.q('
    x x1        x2
    ----------------------
    a 0.8236115 0.7306473
    a 0.3865843 1.01605
    c 0.9931491 1.155324
    c 0.9362009 1.569154
    c 0.4849499 0.09870703
    '))
    >>> kx.q.sql("SELECT * FROM $1 WHERE x='a'", qtable)
    pykx.Table(pykx.q('
    x x1        x2
    ---------------------
    a 0.8236115 0.7306473
    a 0.3865843 1.01605
    a 0.259265  2.805719
    a 0.6140826 1.730398
    a 0.6212161 3.97236
    ..
    '))
    >>> kx.q.qsql.select(qtable, where = 'x=`a')
    pykx.Table(pykx.q('
    x x1        x2
    ---------------------
    a 0.8236115 0.7306473
    a 0.3865843 1.01605
    a 0.259265  2.805719
    a 0.6140826 1.730398
    a 0.6212161 3.97236
    ..
    '))
  • Apply q keyword functions:

    Python

    Copy
    >>> qvec = kx.q.til(10)
    >>> qvec
    pykx.LongVector(pykx.q('0 1 2 3 4 5 6 7 8 9'))
    >>> kx.q.mavg(3, qvec)
    pykx.FloatVector(pykx.q('0 0.5 1 2 3 4 5 6 7 8'))
  • Get help on a q keyword functions (see installation docs):

    Python

    Copy
    >>> help(kx.q.max)
    Help on UnaryPrimitive in pykx:

    pykx.UnaryPrimitive = pykx.UnaryPrimitive(pykx.q('max'))
        • max

        Maximum.

            >>> pykx.q.max([0, 7, 2, 4 , 1, 3])
            pykx.LongAtom(q('7'))


    >>> help(kx.q.abs)
    Help on UnaryPrimitive in pykx:

    pykx.UnaryPrimitive = pykx.UnaryPrimitive(pykx.q('abs'))
        • abs

        Where x is a numeric or temporal, returns the absolute value of x. Null is returned if x is null.

            >>> pykx.q.abs(-5)
            pykx.LongAtom(q('5'))

4. Convert KDB-X objects to Python types

To convert the objects generated via the KDB-X library to the corresponding Python, Numpy, Pandas, and PyArrow types, use py, np, pd, and pa methods. Click on a drop-down below to go through the examples:

Convert to Python

Convert to Numpy

Convert to Pandas

Convert to PyArrow

Python

Copy
    >>> qdictionary = kx.toq({'a': 5, 'b': range(10), 'c': np.random.uniform(low=0.0, high=1.0, size=(5,))})
    >>> qdictionary
    pykx.Dictionary(pykx.q('
    a| 5
    b| 0 1 2 3 4 5 6 7 8 9
    c| 0.01450907 0.9131434 0.5745007 0.961908 0.7609489
    '))
    >>> qdictionary.py()
    {'a': 5, 'b': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 'c': [0.014509072760120034, 0.9131434387527406, 0.5745006683282554, 0.9619080068077892, 0.7609488749876618]}
    >>>
    >>> qvec = kx.toq(np.random.randint(5, size=10))
    >>> qvec.py()
    [0, 2, 4, 1, 2, 1, 0, 1, 0, 1]

Python

Copy
>>> import numpy as np
        >>> random = np.random.random
        >>> randint = np.random.randint
        >>> qvec = kx.q('10?5')
        >>> qvec.np()
        array([0, 2, 4, 1, 2, 1, 0, 1, 0, 1])
        >>> qtab = kx.Table([[random(), randint(0, 5)] for _ in range(5)])
        >>> qtab
        pykx.Table(pykx.q('
        x         x1
        ------------
        0.8247812 4
        0.2149847 0
        0.1007832 2
        0.4520411 4
        0.0196153 0
        '))
        >>> qtab.np()
        rec.array([(0.82478116, 4), (0.21498466, 0), (0.10078323, 2),
                (0.45204113, 4), (0.0196153 , 0)],
                dtype=[('x', '<f8'), ('x1', '<i8')])
                    

Python

Copy
>>> qvec = kx.toq(np.random.randint(5, size=10))
>>> qvec.pd()
0    0
1    2
2    4
3    1
4    2
5    1
6    0
7    1
8    0
9    1
dtype: int64
>>> df = pd.DataFrame(data={'x': [random() for _ in range(5)], 'x1': [randint(0, 4) for _ in range(5)]})
>>> qtab = kx.toq(df)
>>> qtab.pd()
x  x1
0  0.824781   4
1  0.214985   0
2  0.100783   2
3  0.452041   4
4  0.019615   0

If using pandas>=2.0 it is possible to also use the as_arrow keyword argument to convert to pandas types using pyarrow as the backend instead of the default numpy backed pandas objects.

Python

Copy
>>> qvec = kx.toq(np.random.randint(5, size=10))
>>> qvec.pd(as_arrow=True)
0    1
1    2
2    3
3    4
4    2
5    3
6    0
7    0
8    2
9    0
dtype: int64[pyarrow]
>>> df = pd.DataFrame(data={'x': [random() for _ in range(5)], 'x1': [randint(0, 4) for _ in range(5)]})
>>> qtab = kx.toq(df)
>>> qtab.pd(as_arrow=True)
x  x1
0  0.541059   3
1  0.886690   1
2  0.674300   4
3  0.532791   3
4  0.523147   4
>>> qtab.pd(as_arrow=True).dtypes
x     double[pyarrow]
x1     int64[pyarrow]
dtype: object

Python

Copy
>>> qvec = kx.random.random(10, 5)
        >>> qvec.pa()
        <pyarrow.lib.Int64Array object at 0x7ffa678f4e80>
        [
            0,
            2,
            4,
            1,
            2,
            1,
            0,
            1,
            0,
            1
        ]
        >>> df = pd.DataFrame(data={'x': [random() for _ in range(5)], 'x1': [randint(0, 4) for _ in range(5)]})
        >>> qtab = kx.toq(df)
        >>> qtab.pa()
        pyarrow.Table
        x: double
        x1: int64
        ----
        x: [[0.707331785506831,0.03695847895120696,0.7024166621644556,0.3955776423810857,0.7539328513313873]]
        x1: [[4,3,2,3,2]]
                    

Next steps