PyKX native function reference card
This page documents the functions found in the q global namespace that are available in PyKX as attributes of pykx.q
, or as attributes of pykx.QConnection
instances. Refer to the q reference card in the q docs for more details about using these functions in q. This page documents how one might use them from Python via PyKX.
All of these functions take and return q objects, which are wrapped in PyKX as pykx.K
objects. Arguments of other types will have pykx.K
called on them to convert them into q objects. Refer to the PyKX wrappers documentation for more information about pykx.K
objects.
By Category
Not all functions listed on the q reference card are available as attributes of pykx.q
, or as attributes of pykx.QConnection
instances. These include elements such as select
, exec
, update
, and delete
which are not actually q functions, but rather part of the q language itself (i.e. handled by the parser), and functions whose names would result in syntax errors in Python, such as not
and or
.
Because arbitrary q code can be executed using PyKX (except in unlicensed mode, in which none of these functions are available), these limitations can be circumvented as necessary by running q code instead of using the context interface. For example, pykx.q('not')
can be used instead of pykx.q.not
. Consider using the qSQL query documentation as an alternative to writing qSQL queries as q code.
Environment
getenv
Get the value of an environment variable.
>>> pykx.q.getenv('EDITOR')
pykx.CharVector(q('"nvim"'))
gtime
UTC equivalent of local timestamp.
>>> import datetime
>>> pykx.q.gtime(datetime.datetime.fromisoformat('2022-05-22T12:23:45.123'))
pykx.TimestampAtom(q('2022.05.22D16:23:45.123000000'))
ltime
Local equivalent of UTC timestamp.
>>> import datetime
>>> pykx.q.ltime(datetime.datetime.fromisoformat('2022-05-22T12:23:45.123'))
pykx.TimestampAtom(q('2022.05.22D08:23:45.123000000'))
setenv
Set the value of an environment variable.
>>> pykx.q.setenv('RTMP', b'/home/user/temp')
>>> pykx.q.getenv('RTMP')
pykx.CharVector(q('"/home/user/temp"'))
Interpret
eval
Evaluate parse trees.
>>> pykx.q.eval([pykx.q('+'), 2, 3])
pykx.LongAtom(q('5'))
parse
Parse a char vector into a parse tree, which can be evaluated with pykx.q.eval
.
>>> pykx.q.parse(b'{x * x}')
pykx.Lambda(q('{x * x}'))
>>> pykx.q.parse(b'2 + 3')
pykx.List(pykx.q('
+
2
3
'))
reval
Restricted evaluation of a parse tree.
Behaves similar to eval
except the evaluation is blocked from modifying values or global state.
>>> pykx.q.reval(pykx.q.parse(b'til 10'))
pykx.LongVector(q('0 1 2 3 4 5 6 7 8 9'))
show
Print the string representation of the given q object.
Note: show
bypasses typical Python output redirection.
The q function show
prints directly to file descriptor 1, so typical Python output redirection methods, e.g. contextlib.redirect_stdout
, will not affect it.
>>> pykx.q.show(range(5))
0
1
2
3
4
pykx.Identity(q('::'))
system
Execute a system command.
Where x is a string representing a system command and any parameters to it, executes the command and returns any result.
>>> pykx.q.system(b'pwd')
pykx.List(q('"/home/user"'))
value
Returns the value of x.
Input Type | Output Type |
---|---|
dictionary | value of the dictionary |
symbol atom | value of the variable it names |
enumeration | corresponding symbol vector |
string | result of evaluating it in current context |
list | result of evaluating list as a parse tree |
projection | list: function followed by argument/s |
composition | list of composed values |
derived function | argument of the iterator |
operator | internal code |
view | list of metadata |
lambda | structure |
file symbol | content of datafile |
>>> pykx.q.value(pykx.q('`q`w`e!(1 2; 3 4; 5 6)'))
pykx.List(q('
1 2
3 4
5 6
'))
IO
dsave
Write global tables to disk as splayed, enumerated, indexed q tables.
>>> from pathlib import Path
>>> pykx.q['t'] = kx.Table(data={'x': [1, 2, 3], 'y': [10, 20, 30]})
>>> pykx.q.dsave(Path('v'), 't')
pykx.SymbolAtom(q('`t'))
get
Read or memory-map a variable or q data file.
>>> pykx.q['a'] = 10
>>> pykx.q.get('a')
pykx.LongAtom(q('10'))
hclose
Where x is a connection handle, closes the connection, and destroys the handle.
>>> pykx.q.hclose(pykx.q('3i'))
hcount
Size of a file in bytes.
>>> pykx.q.hcount('example.txt')
pykx.LongAtom(q('11'))
hdel
Where x
is a file symbol atom, deletes the file or folder (if empty), and returns x
.
>>> pykx.q.hdel('example.txt')
hopen
Open a connection to a file or process.
>>> pykx.q.hopen('example.txt')
pykx.IntAtom(q('3i'))
hsym
Convert symbols to handle symbols, which can be used for I/O as file descriptors or handles.
>>> pykx.q.hsym('10.43.23.197')
pykx.SymbolAtom(q('`:10.43.23.197'))
load
Load binary data from a file.
>>> pykx.q['t'] = pykx.Table([[1, 10], [2, 20], [3, 30]], columns=['x', 'y'])
>>> pykx.q('t')
pykx.Table(pykx.q('
x y
----
1 10
2 20
3 30
'))
>>> pykx.q.save('t') # Save t to disk
pykx.SymbolAtom(pykx.q('`:t'))
>>> pykx.q('delete t from `.') # Delete t from memory
pykx.SymbolAtom(pykx.q('`.'))
>>> pykx.q('t') # t is not longer defined
Traceback (most recent call last):
pykx.exceptions.QError: t
>>> pykx.q.load('t') # Load t from disk
pykx.SymbolAtom(pykx.q('`t'))
>>> pykx.q('t')
pykx.Table(pykx.q('
x y
----
1 10
2 20
3 30
'))
read0
Read text from a file or process handle.
>>> pykx.q.read0('example.txt')
pykx.List(q('
"Hello"
"World"
'))
read1
Read bytes from a file or named pipe.
>>> pykx.q.read1('example.txt')
pykx.ByteVector(q('0x48656c6c6f0a576f726c64'))
rload
Load a splayed table from a directory.
>>> pykx.q.rload('t')
>>> pykx.q('t')
pykx.Table(q('
x y
----
1 10
2 20
3 30
'))
rsave
Write a table splayed to a directory.
>>> pykx.q['t'] = pykx.Table([[1, 10], [2, 20], [3, 30]])
>>> pykx.q.rsave('t')
pykx.SymbolAtom(q('`:t/'))
save
Write global data to file or splayed to a directory.
>>> pykx.q['t'] = pykx.Table([[1, 10], [2, 20], [3, 30]])
>>> pykx.q.save('t')
pykx.SymbolAtom(q('`:t'))
set
Assign a value to a global variable.
Persist an object as a file or directory.
Types | Result |
---|---|
pykx.q.set(nam, y) | set global nam to y |
pykx.q.set(fil, y) | write y to a file |
pykx.q.set(dir, y) | splay y to a directory |
pykx.q.set([fil, lbs, alg, lvl], y) | write y to a file, compressed |
pykx.q.set([dir, lbs, alg, lvl], y) | splay y to a directory, compressed |
pykx.q.set([dir, dic], y) | splay y to a directory, compressed |
Where
Abbreviation | K type | Explanation |
---|---|---|
alg | integer atom | compression algorithm |
dic | dictionary | compression specifications |
dir | filesymbol | directory in the filesystem |
fil | filesymbol | file in the filesystem |
lbs | integer atom | logical block size |
lvl | integer atom | compression level |
nam | symbol atom | valid q name |
t | table | |
y | (any) | any q object |
Compression parameters alg, lbs, and lvl
Compression specification dictionary
>>> pykx.q.set('a', 42)
pykx.SymbolAtom(q('`a'))
>>> pykx.q('a')
pykx.LongAtom(q('42'))
Iterate
each
Iterate over list and apply a function to each element.
>>> pykx.q.each(pykx.q.count, [b'Tis', b'but', b'a', b'scratch'])
pykx.LongVector(q('3 3 1 7'))
>>> pykx.q.each(pykx.q.sums, [[2, 3, 4], [[5, 6], [7, 8]], [9, 10, 11, 12]])
pykx.List(q('
2 5 9
((5;6);12 14)
9 19 30 42
'))
over
The keywords over and scan
are covers for the accumulating iterators, Over and Scan. It is good style to use over and scan with unary and binary values.
Just as with Over and Scan, over and scan share the same syntax and perform the same computation; but while scan returns the result of each evaluation, over returns only the last.
>>> pykx.q.over(pykx.q('*'), [1, 2, 3, 4, 5])
pykx.LongAtom(q('120'))
peach
each
and peach perform the same computation and return the same result, but peach will parallelize the work across available threads.
>>> pykx.q.peach(pykx.q.count, [b'Tis', b'but', b'a', b'scratch'])
pykx.LongVector(q('3 3 1 7'))
>>> pykx.q.peach(pykx.q.sums, [[2, 3, 4], [[5, 6], [7, 8]], [9, 10, 11, 12]])
pykx.List(q('
2 5 9
((5;6);12 14)
9 19 30 42
'))
prior
Applies a function to each item of x
and the item preceding it, and returns a result of the same length.
>>> pykx.q.prior(pykx.q('+'), [1, 2, 3, 4, 5])
pykx.LongVector(pykx.q('1 3 5 7 9'))
>>> pykx.q.prior(lambda x, y: x + y, pykx.LongVector([1, 2, 3, 4, 5]))
pykx.LongVector(pykx.q('0N 3 5 7 9'))
scan
The keywords over and scan are covers for the accumulating iterators, Over and Scan. It is good style to use over and scan with unary and binary values.
Just as with Over and Scan, over and scan share the same syntax and perform the same computation; but while scan returns the result of each evaluation, over returns only the last.
>>> pykx.q.scan(pykx.q('+'), [1, 2, 3, 4, 5])
pykx.LongVector(q('1 3 6 10 15'))
Join
aj
Performs an as-of join across temporal columns in tables. Returns a table with records from the left-join of the first table and the second table. For each record in the first table, it is matched with the second table over the columns specified in the first input parameter and if there is a match the most recent match will be joined to the record.
The resulting time column is the value of the boundry used in the first table.
>>> import pandas as pd
>>> import numpy as np
>>> df1 = pd.DataFrame({
... 'time': np.array([36061, 36063, 36064], dtype='timedelta64[s]'),
... 'sym': ['msft', 'ibm', 'ge'], 'qty': [100, 200, 150]
... })
>>> df2 = pd.DataFrame({
... 'time': np.array([36060, 36060, 36060, 36062], dtype='timedelta64[s]'),
... 'sym': ['ibm', 'msft', 'msft', 'ibm'], 'qty': [100, 99, 101, 98]
... })
>>> pykx.q.aj(pykx.SymbolVector(['sym', 'time']), df1, df2)
pykx.Table(q('
time sym qty
-----------------------------
0D10:01:01.000000000 msft 101
0D10:01:03.000000000 ibm 98
0D10:01:04.000000000 ge 150
'))
aj0
Performs an as-of join across temporal columns in tables. Returns a table with records from the left-join of the first table and the second table. For each record in the first table, it is matched with the second table over the columns specified in the first input parameter and if there is a match the most recent match will be joined to the record.
The resulting time column is the actual time of the last value in the second table.
>>> import pandas as pd
>>> import numpy as np
>>> df1 = pd.DataFrame({
... 'time': np.array([36061, 36063, 36064], dtype='timedelta64[s]'),
... 'sym': ['msft', 'ibm', 'ge'], 'qty': [100, 200, 150]
... })
>>> df2 = pd.DataFrame({
... 'time': np.array([36060, 36060, 36060, 36062], dtype='timedelta64[s]'),
... 'sym': ['ibm', 'msft', 'msft', 'ibm'], 'qty': [100, 99, 101, 98]
... })
>>> pykx.q.aj0(pykx.SymbolVector(['sym', 'time']), df1, df2)
pykx.Table(q('
time sym qty
-----------------------------
0D10:01:00.000000000 msft 101
0D10:01:02.000000000 ibm 98
0D10:01:04.000000000 ge 150
'))
ajf
Performs an as-of join across temporal columns in tables with null values being filled. Returns a table with records from the left-join of the first table and the second table. For each record in the first table, it is matched with the second table over the columns specified in the first input parameter and if there is a match the most recent match will be joined to the record.
The resulting time column is the value of the boundary used in the first table.
>>> import pandas as pd
>>> import numpy as np
>>> df1 = pd.DataFrame({
... 'time': np.array([1, 1], dtype='timedelta64[s]'),
... 'sym': ['a', 'b'],
... 'p': pykx.LongVector([0, 1]),
... 'n': ['r', 's']
... })
>>> df2 = pd.DataFrame({
... 'time': np.array([1, 1], dtype='timedelta64[s]'),
... 'sym':['a', 'b'],
... 'p': pykx.q('1 0N')
... })
>>> pykx.q.ajf(pykx.SymbolVector(['sym', 'time']), df1, df2)
pykx.Table(q('
time sym p n
----------------------------
0D00:00:01.000000000 a 1 r
0D00:00:01.000000000 b 1 s
'))
ajf0
Performs an as-of join across temporal columns in tables with null values being filled. Returns a table with records from the left-join of the first table and the second table. For each record in the first table, it is matched with the second table over the columns specified in the first input parameter and if there is a match the most recent match will be joined to the record.
The resulting time column is the actual time of the last value in the second table.
>>> import pandas as pd
>>> import numpy as np
>>> df1 = pd.DataFrame({
... 'time': np.array([1, 1], dtype='timedelta64[s]'),
... 'sym':['a', 'b'],
... 'p': pykx.LongVector([0, 1]),
... 'n': ['r', 's']
... })
>>> df2 = pd.DataFrame({
... 'time': np.array([1, 1], dtype='timedelta64[s]'),
... 'sym': ['a', 'b'],
... 'p': pykx.q('1 0N')
... })
>>> pykx.q.ajf0(pykx.SymbolVector(['sym', 'time']), df1, df2)
pykx.Table(q('
time sym p n
----------------------------
0D00:00:01.000000000 a 1 r
0D00:00:01.000000000 b 1 s
'))
asof
Performs an as-of join across temporal columns in tables. The last column the second table must be temporal and correspond to a column in the first table argument. The return is the data from the first table is the last time that is less than or equal to the time in the second table per key. The time column will be removed from the output.
>>> import pandas as pd
>>> import numpy as np
>>> df1 = pd.DataFrame({
... 'time': np.array([1, 2, 3, 4], dtype='timedelta64[s]'),
... 'sym': ['a', 'a', 'b', 'b'], 'p': pykx.LongVector([2, 4, 6, 8])})
>>> df2 = pd.DataFrame({'sym':['b'], 'time': np.array([3], dtype='timedelta64[s]')})
>>> pykx.q.asof(df1, df2)
pykx.Table(q('
p
-
6
'))
ej
Equi join. The result has one combined record for each row in the second table that matches the first table on the columns specified in the first function parameter.
>>> import pandas as pd
>>> df1 = pd.DataFrame({'sym':['a', 'a', 'b', 'a', 'c', 'b', 'c', 'a'], 'p': pykx.LongVector([2, 4, 6, 8, 1, 3, 5, 7])})
>>> df2 = pd.DataFrame({'sym':['a', 'b'], 'w': ['alpha', 'beta']})
>>> pykx.q.ej('sym', df1, df2)
pykx.Table(q('
sym p w
-----------
a 2 alpha
a 4 alpha
b 6 beta
a 8 alpha
b 3 beta
a 7 alpha
'))
ij
Inner join. The result has one combined record for each row in the first table that matches the second table on the columns specified in the first function parameter.
>>> import pandas as pd
>>> df1 = pd.DataFrame({'sym':['IBM', 'FDP', 'FDP', 'FDP', 'IBM', 'MSFT'], 'p': pykx.LongVector([7, 8, 6, 5, 2, 5])})
>>> df2 = pd.DataFrame({'sym':['IBM', 'MSFT'], 'ex': ['N', 'CME'], 'MC': pykx.LongVector([1000, 250])})
>>> df2 = pykx.q.xkey('sym', df2)
>>> pykx.Table(df1)
pykx.Table(q('
sym p
------
IBM 7
FDP 8
FDP 6
FDP 5
IBM 2
MSFT 5
'))
>>> df2
pykx.KeyedTable(q('
sym | ex MC
----| --------
IBM | N 1000
MSFT| CME 250
'))
>>> pykx.q.ij(df1, df2)
pykx.Table(q('
sym p ex MC
---------------
IBM 7 N 1000
IBM 2 N 1000
MSFT 5 CME 250
'))
ijf
Inner join nulls filled. The result has one combined record for each row in the first table that matches the second table on the columns specified in the first function parameter.
>>> import pandas as pd
>>> df1 = pd.DataFrame({'sym':['IBM', 'FDP', 'FDP', 'FDP', 'IBM', 'MSFT'], 'p': pykx.LongVector([7, 8, 6, 5, 2, 5])})
>>> df2 = pd.DataFrame({'sym':['IBM', 'MSFT'], 'ex': ['N', 'CME'], 'MC': pykx.LongVector([1000, 250])})
>>> b = pykx.q.xkey('sym', df2)
>>> pykx.Table(df1)
pykx.Table(q('
sym p
------
IBM 7
FDP 8
FDP 6
FDP 5
IBM 2
MSFT 5
'))
>>> df2
pykx.KeyedTable(q('
sym | ex MC
----| --------
IBM | N 1000
MSFT| CME 250
'))
>>> pykx.q.ijf(df1, df2)
pykx.Table(q('
sym p ex MC
---------------
IBM 7 N 1000
IBM 2 N 1000
MSFT 5 CME 250
'))
lj
Left join. For each record in the first table, the result has one record with the columns of second table joined to columns of the first using the primary keys of the second table, if no value is present in the second table the record will contain null values in the place of the columns of the second table.
>>> import pandas as pd
>>> df1 = pd.DataFrame({'sym':['IBM', 'FDP', 'FDP', 'FDP', 'IBM', 'MSFT'], 'p': pykx.LongVector([7, 8, 6, 5, 2, 5])})
>>> df2 = pd.DataFrame({'sym':['IBM', 'MSFT'], 'ex': ['N', 'CME'], 'MC': pykx.LongVector([1000, 250])})
>>> b = pykx.q.xkey('sym', df2)
>>> pykx.Table(df2)
pykx.Table(q('
sym p
------
IBM 7
FDP 8
FDP 6
FDP 5
IBM 2
MSFT 5
'))
>>> df1
pykx.KeyedTable(q('
sym | ex MC
----| --------
IBM | N 1000
MSFT| CME 250
'))
>>> pykx.q.lj(df1, df2)
pykx.Table(q('
sym p ex MC
---------------
IBM 7 N 1000
FDP 8
FDP 6
FDP 5
IBM 2 N 1000
MSFT 5 CME 250
'))
ljf
Left join nulls filled. For each record in the first table, the result has one record with the columns of second table joined to columns of the first using the primary keys of the second table, if no value is present in the second table the record will contain null values in the place of the columns of the second table.
>>> import pandas as pd
>>> df1 = pd.DataFrame({'sym':['IBM', 'FDP', 'FDP', 'FDP', 'IBM', 'MSFT'], 'p': pykx.LongVector([7, 8, 6, 5, 2, 5])})
>>> df2 = pd.DataFrame({'sym':['IBM', 'MSFT'], 'ex': ['N', 'CME'], 'MC': pykx.LongVector([1000, 250])})
>>> b = pykx.q.xkey('sym', df2)
>>> pykx.Table(df1)
pykx.Table(q('
sym p
------
IBM 7
FDP 8
FDP 6
FDP 5
IBM 2
MSFT 5
'))
>>> df1
pykx.KeyedTable(q('
sym | ex MC
----| --------
IBM | N 1000
MSFT| CME 250
'))
>>> pykx.q.ljf(df1, df2)
pykx.Table(q('
sym p ex MC
---------------
IBM 7 N 1000
FDP 8
FDP 6
FDP 5
IBM 2 N 1000
MSFT 5 CME 250
'))
pj
Plus join. For each record in the first table, the result has one record with the columns of second table joined to columns of the first using the primary keys of the second table, if a value is present it is added to the columns of the first table, if no value is present the columns are left unchanged and new columns are set to 0.
>>> import pandas as pd
>>> df1 = pd.DataFrame({'a': pykx.LongVector([1, 2, 3]), 'b':['x', 'y', 'z'], 'c': pykx.LongVector([10, 20, 30])})
>>> pykx.Table(df1)
pykx.Table(q('
a b c
------
1 x 10
2 y 20
3 z 30
'))
>>> df2 = pd.DataFrame({
... 'a': pykx.LongVector([1, 3]),
... 'b':['x', 'z'],
... 'c': pykx.LongVector([1, 2]),
... 'd': pykx.LongVector([10, 20])
... })
>>> df2 = pykx.q.xkey(pykx.SymbolVector(['a', 'b']), df2)
pykx.KeyedTable(q('
a b| c d
---| ----
1 x| 1 10
3 z| 2 20
'))
>>> pykx.q.pj(df1, df2)
pykx.Table(q('
a b c d
---------
1 x 11 10
2 y 20 0
3 z 32 20
'))
uj
Union join. Where the first table and the second table are both keyed or both unkeyed tables, returns the union of the columns, filled with nulls where necessary. If the tables have matching key columns then the records in the second table will be used to update the first table, if the tables are not keyed then the records from the second table will be joined onto the end of the first table.
>>> import pandas as pd
>>> df1 = pd.DataFrame({'sym':['IBM', 'FDP', 'FDP', 'FDP', 'IBM', 'MSFT'], 'p': pykx.LongVector([7, 8, 6, 5, 2, 5])})
>>> df2 = pd.DataFrame({'sym':['IBM', 'MSFT'], 'ex': ['N', 'CME'], 'MC': pykx.LongVector([1000, 250])})
>>> df1
sym p
0 IBM 7
1 FDP 8
2 FDP 6
3 FDP 5
4 IBM 2
5 MSFT 5
>>> df2
sym ex MC
0 IBM N 1000
1 MSFT CME 250
>>> pykx.q.uj(df1, df2)
pykx.Table(q('
sym p ex MC
---------------
IBM 7
FDP 8
FDP 6
FDP 5
IBM 2
MSFT 5
IBM N 1000
MSFT CME 250
'))
ujf
Union join nulls filled. Where the first table and the second table are both keyed or both unkeyed tables, returns the union of the columns, filled with nulls where necessary. If the tables have matching key columns then the records in the second table will be used to update the first table, if the tables are not keyed then the records from the second table will be joined onto the end of the first table.
>>> import pandas as pd
>>> df1 = pd.DataFrame({'sym':['IBM', 'FDP', 'FDP', 'FDP', 'IBM', 'MSFT'], 'p': pykx.LongVector([7, 8, 6, 5, 2, 5])})
>>> df2 = pd.DataFrame({'sym':['IBM', 'MSFT'], 'ex': ['N', 'CME'], 'MC': pykx.LongVector([1000, 250])})
>>> df1
sym p
0 IBM 7
1 FDP 8
2 FDP 6
3 FDP 5
4 IBM 2
5 MSFT 5
>>> df2
sym ex MC
0 IBM N 1000
1 MSFT CME 250
>>> pykx.q.ujf(df1, df2)
pykx.Table(q('
sym p ex MC
---------------
IBM 7
FDP 8
FDP 6
FDP 5
IBM 2
MSFT 5
IBM N 1000
MSFT CME 250
'))
wj
Window join. Returns for each record in the table, a record with additional columns c0
and c1
, which contain the results of the aggregation functions applied to values over the matching intervals defined in the first parameter of the function.
>>> import pandas as pd
>>> import numpy as np
>>> pykx.q('t: ([]sym:3#`ibm;time:10:01:01 10:01:04 10:01:08;price:100 101 105)')
pykx.Table(pykx.q('
sym time price
------------------
ibm 10:01:01 100
ibm 10:01:04 101
ibm 10:01:08 105
'))
>>> df_t = pd.DataFrame({
'sym': ['ibm', 'ibm', 'ibm'],
'time': np.array([36061, 36064, 36068], dtype='timedelta64[s]'),
'price': pykx.LongVector([100, 101, 105])
})
sym time price
0 ibm 0 days 10:01:01 100
1 ibm 0 days 10:01:04 101
2 ibm 0 days 10:01:08 105
>>> pykx.q('q:([]sym:`ibm; time:10:01:01+til 9; ask: (101 103 103 104 104 107 108 107 108); bid: (98 99 102 103 103 104 106 106 107))')
pykx.Table(pykx.q('
sym time ask bid
--------------------
ibm 10:01:01 101 98
ibm 10:01:02 103 99
ibm 10:01:03 103 102
ibm 10:01:04 104 103
ibm 10:01:05 104 103
ibm 10:01:06 107 104
ibm 10:01:07 108 106
ibm 10:01:08 107 106
ibm 10:01:09 108 107
'))
>>> f = pykx.SymbolVector(['sym', 'time'])
>>> w = pykx.q('-2 1+\:t.time')
>>> pykx.q.wj(w, f, df_t, pykx.q('(q;(max;`ask);(min;`bid))'))
pykx.Table(pykx.q('
sym time price ask bid
--------------------------
ibm 10:01:01 100 103 98
ibm 10:01:04 101 104 99
ibm 10:01:08 105 108 104
'))
wj1
Window join. Returns for each record in the table, a record with additional columns c0
and c1
, which contain the results of the aggregation functions applied to values over the matching intervals defined in the first parameter of the function.
>>> import pandas as pd
>>> import numpy as np
>>> pykx.q('t: ([]sym:3#`ibm;time:10:01:01 10:01:04 10:01:08;price:100 101 105)')
pykx.Table(pykx.q('
sym time price
------------------
ibm 10:01:01 100
ibm 10:01:04 101
ibm 10:01:08 105
'))
>>> df_t = pd.DataFrame({
... 'sym': ['ibm', 'ibm', 'ibm'],
... 'time': np.array([36061, 36064, 36068], dtype='timedelta64[s]'),
... 'price': pykx.LongVector([100, 101, 105])
... })
sym time price
0 ibm 0 days 10:01:01 100
1 ibm 0 days 10:01:04 101
2 ibm 0 days 10:01:08 105
>>> pykx.q('q:([]sym:`ibm; time:10:01:01+til 9; ask: (101 103 103 104 104 107 108 107 108); bid: (98 99 102 103 103 104 106 106 107))')
pykx.Table(pykx.q('
sym time ask bid
--------------------
ibm 10:01:01 101 98
ibm 10:01:02 103 99
ibm 10:01:03 103 102
ibm 10:01:04 104 103
ibm 10:01:05 104 103
ibm 10:01:06 107 104
ibm 10:01:07 108 106
ibm 10:01:08 107 106
ibm 10:01:09 108 107
'))
>>> f = pykx.SymbolVector(['sym', 'time'])
>>> w = pykx.q('-2 1+\:t.time')
>>> pykx.q.wj(w, f, df_t, pykx.q('(q;(max;`ask);(min;`bid))'))
pykx.Table(pykx.q('
sym time price ask bid
--------------------------
ibm 10:01:01 100 103 98
ibm 10:01:04 101 104 99
ibm 10:01:08 105 108 104
'))
List
count
Count the items of a list or dictionary.
>>> pykx.q.count([1, 2, 3])
pykx.LongAtom(q('3'))
cross
Returns all possible combinations of x and y.
>>> pykx.q.cross([1, 2, 3], [4, 5, 6])
pykx.List(q('
1 4
1 5
1 6
2 4
2 5
2 6
3 4
3 5
3 6
'))
cut
Cut a list or table into sub-arrays.
>>> pykx.q.cut(3, range(10))
pykx.List(q('
0 1 2
3 4 5
6 7 8
,9
'))
enlist
Returns a list with its arguments as items.
>>> pykx.q.enlist(1, 2, 3, 4)
pykx.LongVector(q('1 2 3 4'))
fills
Replace nulls with preceding non-nulls.
>>> a = pykx.q('0N 1 2 0N 0N 2 3 4 5 0N 4')
>>> pykx.q.fills(a)
pykx.LongVector(q('0N 1 2 2 2 2 3 4 5 5 4'))
first
First item of a list
>>> pykx.q.first([1, 2, 3, 4, 5])
pykx.LongAtom(q('1'))
flip
Returns x transposed, where x may be a list of lists, a dictionary or a table.
>>> pykx.q.flip([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
pykx.List(q('
1 6
2 7
3 8
4 9
5 10
'))
group
Returns a dictionary in which the keys are the distinct items of x, and the values the indexes where the distinct items occur.
The order of the keys is the order in which they appear in x.
>>> pykx.q.group(b'mississippi')
pykx.Dictionary(q('
m| ,0
i| 1 4 7 10
s| 2 3 5 6
p| 8 9
'))
inter
Intersection of two lists or dictionaries.
>>> pykx.q.inter([1, 2, 3], [2, 3, 4])
pykx.LongVector(q('2 3'))
last
Last item of a list
>>> pykx.q.last([1, 2, 3])
pykx.LongAtom(q('3'))
mcount
Returns the x-item moving counts of the non-null items of y. The first x items of the result are the counts so far, and thereafter the result is the moving count.
>>> pykx.q.mcount(3, pykx.q('1 2 3 4 5 0N 6 7 8'))
pykx.IntVector(q('1 2 3 3 3 2 2 2 3i'))
next
Next items in a list.
>>> pykx.q.next([1, 2, 3, 4])
pykx.LongVector(q('2 3 4 0N'))
prev
Immediately preceding items in a list.
>>> pykx.q.prev([1, 2, 3, 4])
pykx.LongVector(q('0N 1 2 3'))
raze
Return the items of x joined, collapsing one level of nesting.
>>> pykx.q.raze([[1, 2], [3, 4]])
pykx.LongVector(q('1 2 3 4'))
reverse
Reverse the order of items of a list or dictionary.
>>> pykx.q.reverse([1, 2, 3, 4, 5])
pykx.List(q('
5
4
3
2
1
'))
rotate
Shift the items of a list to the left or right.
>>> pykx.q.rotate(2, [1, 2, 3, 4, 5])
pykx.LongVector(q('3 4 5 1 2'))
sublist
Select a sublist of a list.
>>> pykx.q.sublist(2, [1, 2, 3, 4, 5])
pykx.LongVector(q('1 2'))
sv
"Scalar from vector"
- join strings, symbols, or filepath elements
- decode a vector to an atom
>>> pykx.q.sv(10, [1, 2, 3, 4])
pykx.LongAtom(q('1234'))
til
First x natural numbers.
>>> pykx.q.til(10)
pykx.LongVector(q('0 1 2 3 4 5 6 7 8 9'))
union
Union of two lists.
>>> pykx.q.union([1, 2, 3, 3, 5], [2, 4, 6, 8])
pykx.LongVector(q('1 2 3 5 4 6 8'))
vs
"Vector from scalar"
- partition a symbol, string, or bytestream
- encode a vector from an atom, or a matrix from a vector
>>> pykx.q.vs(b',', b'one,two,three')
pykx.List(q('
"one"
"two"
"three"
'))
where
Copies of indexes of a list or keys of a dictionary.
>>> pykx.q.where(pykx.BooleanVector([True, False, True, True, False]))
pykx.LongVector(q('0 2 3'))
>>> pykx.q.where(pykx.q('1 0 0 1 0 1 1'))
pykx.LongVector(q('0 3 5 6'))
xprev
Nearby items in a list.
>>> pykx.q.xprev(2, [1, 2, 3, 4, 5, 6])
pykx.LongVector(q('0N 0N 1 2 3 4'))
There is no xnext
function, but xprev
with a negative number as its first argument can achieve this.
>>> pykx.q.xprev(-2, [1, 2, 3, 4, 5, 6])
pykx.LongVector(q('3 4 5 6 0N 0N'))
Logic
all
Everything is true.
>>> pykx.q.all([True, True, True, True])
pykx.BooleanAtom(q('1b'))
>>> pykx.q.all([True, True, False, True])
pykx.BooleanAtom(q('0b'))
any
Something is true.
>>> pykx.q.any([False, False, True, False])
pykx.BooleanAtom(q('1b'))
>>> pykx.q.any([False, False])
pykx.BooleanAtom(q('0b'))
Math
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'))
acos
The arccosine of x; that is, the value whose cosine is x. The result is in radians and lies between 0 and π.
>>> pykx.q.acos(0.5)
pykx.FloatAtom(q('1.047198'))
asin
The arcsine of x; that is, the value whose sine is x. The result is in radians and lies between -π / 2 and π / 2. (The range is approximate due to rounding errors). Null is returned if the argument is not between -1 and 1.
>>> pykx.q.asin(0.5)
pykx.FloatAtom(q('0.5235988'))
atan
The arctangent of x; that is, the value whose tangent is x. The result is in radians and lies between -π / 2 and π / 2.
>>> pykx.q.atan(0.5)
pykx.FloatAtom(q('0.4636476'))
avg
Arithmetic mean.
>>> pykx.q.avg([1, 2, 3, 4, 7])
pykx.FloatAtom(q('3.4'))
avgs
Running mean.
>>> pykx.q.avgs([1, 2, 3, 4, 7])
pykx.FloatVector(q('1 1.5 2 2.5 3.4'))
ceiling
Round up.
>>> pykx.q.ceiling([-2.7, -1.1, 0, 1.1, 2.7])
pykx.LongVector(q('-2 -1 0 2 3'))
cor
Correlation.
>>> pykx.q.cor(pykx.LongVector([29, 10, 54]), pykx.LongVector([1, 3, 9]))
pykx.FloatAtom(q('0.7727746'))
cos
The cosine of x, taken to be in radians. The result is between -1 and 1, or null if the argument is null or infinity.
>>> pykx.q.cos(0.2)
pykx.FloatAtom(q('0.9800666'))
cov
Where x and y are conforming numeric lists returns their covariance as a floating-point number. Applies to all numeric data types and signals an error with temporal types, char and sym.
>>> pykx.q.cov(pykx.LongVector([29, 10, 54]), pykx.LongVector([1, 3, 9]))
pykx.FloatAtom(q('47.33333'))
deltas
Where x is a numeric or temporal vector, returns differences between consecutive pairs of its items.
>>> pykx.q.deltas(pykx.LongVector([1, 4, 9, 16]))
pykx.LongVector(q('1 3 5 7'))
dev
Standard deviation.
>>> pykx.q.dev(pykx.LongVector([10, 343, 232, 55]))
pykx.FloatAtom(q('134.3484'))
div
Integer division.
>>> pykx.q.div(7, 3)
pykx.LongAtom(q('2'))
ema
The cosine of x, taken to be in radians. The result is between -1 and 1, or null if the argument is null or infinity.
>>> pykx.q.ema(0.5, [1, 2, 3, 4, 5])
pykx.FloatVector(q('1 1.5 2.25 3.125 4.0625'))
exp
Raise e to a power.
>>> pykx.q.exp(1)
pykx.FloatAtom(q('2.718282'))
floor
Round down.
>>> pykx.q.floor([-2.7, -1.1, 0, 1.1, 2.7])
pykx.LongVector(q('-3 -2 0 1 2'))
inv
Matrix inverse.
>>> a = pykx.q('3 3# 2 4 8 3 5 6 0 7 1f')
pykx.List(q('
2 4 8
3 5 6
0 7 1
'))
>>> pykx.q.inv(a)
pykx.List(q('
-0.4512195 0.6341463 -0.195122
-0.03658537 0.02439024 0.1463415
0.2560976 -0.1707317 -0.02439024
'))
log
Natural logarithm.
>>> pykx.q.log([1, 2, 3])
pykx.FloatVector(q('0 0.6931472 1.098612'))
lsq
Least squares, matrix divide.
>>> a = pykx.q('1f+3 4#til 12')
pykx.List(q('
1 2 3 4
5 6 7 8
9 10 11 12
'))
>>> b = pykx.q('4 4#2 7 -2 5 5 3 6 1 -2 5 2 7 5 0 3 4f')
pykx.List(q('
2 7 -2 5
5 3 6 1
-2 5 2 7
5 0 3 4
'))
>>> pykx.q.lsq(a, b)
pykx.List(q('
-0.1233333 0.16 0.4766667 0.28
0.07666667 0.6933333 0.6766667 0.5466667
0.2766667 1.226667 0.8766667 0.8133333
'))
mavg
Moving averages.
>>> pykx.q.mavg(3, [1, 2, 3, 5, 7, 10])
pykx.FloatVector(q('1 1.5 2 3.333333 5 7.333333'))
max
Maximum.
>>> pykx.q.max([0, 7, 2, 4 , 1, 3])
pykx.LongAtom(q('7'))
maxs
Maximums.
>>> pykx.q.maxs([1, 2, 5, 4, 7, 1, 2])
pykx.LongVector(q('1 2 5 5 7 7 7'))
mdev
Moving deviations.
>>> pykx.q.mdev(3, [1, 2, 5, 4, 7, 1, 2])
pykx.FloatVector(q('0 0.5 1.699673 1.247219 1.247219 2.44949 2.624669'))
med
Median.
>>> pykx.q.med([1, 2, 3, 4, 4, 1, 2, 4, 5])
pykx.FloatAtom(q('3f'))
min
Minimum.
>>> pykx.q.min([7, 5, 2, 4, 6, 5, 1, 4])
pykx.LongAtom(q('1'))
mins
Minimums.
>>> pykx.q.mins([7, 5, 2, 4, 6, 5, 1, 4])
pykx.LongVector(q('7 5 2 2 2 2 1 1'))
mmax
Moving maximums.
>>> pykx.q.mmax(4, [7, 5, 2, 4, 6, 5, 1, 4])
pykx.LongVector(q('7 7 7 7 6 6 6 6'))
mmin
Moving minimums.
>>> pykx.q.mmin(4, pykx.LongVector([7, 5, 2, 4, 6, 5, 1, 4]))
pykx.LongVector(q('7 5 2 2 2 2 1 1'))
mmu
Matrix multiply, dot product.
>>> a = pykx.q('2 4#2 4 8 3 5 6 0 7f')
>>> a
pykx.List(q('
2 4 8 3
5 6 0 7
'))
>>> b = pykx.q('4 3#"f"$til 12')
>>> b
pykx.List(q('
0 1 2
3 4 5
6 7 8
9 10 11
'))
>>> pykx.q.mmu(a, b)
pykx.List(q('
87 104 121
81 99 117
'))
mod
Modulus.
>>> pykx.q.mod([1, 2, 3, 4, 5, 6, 7], 4)
pykx.LongVector(q('1 2 3 0 1 2 3'))
msum
Moving sums.
>>> pykx.q.msum(3, [1, 2, 3, 4, 5, 6, 7])
pykx.LongVector(q('1 3 6 9 12 15 18'))
neg
Negate.
>>> pykx.q.neg([2, 0, -1, 3, -5])
pykx.LongVector(q('-2 0 1 -3 5'))
prd
Product.
>>> pykx.q.prd([1, 2, 3, 4, 5])
pykx.LongAtom(q('120'))
prds
Cumulative products.
>>> pykx.q.prds([1, 2, 3, 4, 5])
pykx.LongVector(q('1 2 6 24 120'))
rand
Pick randomly.
>>> pykx.q.rand([1, 2, 3, 4, 5])
pykx.LongAtom(q('2'))
ratios
Ratios between items.
>>> pykx.q.ratios([1, 2, 3, 4, 5])
pykx.FloatVector(q('0n 2 1.5 1.333333 1.25'))
reciprocal
Reciprocal of a number.
>>> pykx.q.reciprocal([1, 0, 3])
pykx.FloatVector(q('1 0w 0.3333333'))
scov
Sample covariance.
>>> pykx.q.scov(pykx.LongVector([2, 3, 5, 7]), pykx.LongVector([4, 3, 0, 2]))
pykx.FloatAtom(q('-2.416667'))
sdev
Sample standard deviation.
>>> pykx.q.sdev(pykx.LongVector([10, 343, 232, 55]))
pykx.FloatAtom(q('155.1322'))
signum
Where x (or its underlying value for temporals) is
- null or negative, returns
-1i
- zero, returns
0i
- positive, returns
1i
>>> pykx.q.signum([-2, 0, 1, 3])
pykx.IntVector(q('-1 0 1 1i'))
sin
Sine.
>>> pykx.q.sin(0.5)
pykx.FloatAtom(q('0.4794255'))
sqrt
Square root.
>>> pykx.q.sqrt([-1, 0, 25, 50])
pykx.FloatVector(q('0n 0 5 7.071068'))
sum
Total.
>>> pykx.q.sum(pykx.LongVector([2, 3, 5, 7]))
pykx.LongAtom(q('17'))
sums
Cumulative total.
>>> pykx.q.sums(pykx.LongVector([2, 3, 5, 7]))
pykx.LongVector(q('2 5 10 17'))
svar
Sample variance.
>>> pykx.q.svar(pykx.LongVector([2, 3, 5, 7]))
pykx.FloatAtom(q('4.916667'))
tan
Tangent.
>>> pykx.q.tan(0.5)
pykx.FloatAtom(q('0.5463025'))
var
Variance.
>>> pykx.q.var(pykx.LongVector([2, 3, 5, 7]))
pykx.FloatAtom(q('3.6875'))
wavg
Weighted average.
>>> pykx.q.wavg([2, 3, 4], [1, 2 ,4])
pykx.FloatAtom(q('2.666667'))
within
Check bounds.
>>> pykx.q.within([1, 3, 10, 6, 4], [2, 6])
pykx.BooleanVector(q('01011b'))
wsum
Weighted sum.
>>> pykx.q.wsum([2, 3, 4], [1, 2, 4]) # equivalent to 2 * 1 + 3 * 2 + 4 * 4
pykx.LongAtom(q('24'))
xexp
Raise x to a power.
>>> pykx.q.xexp(2, 8)
pykx.FloatAtom(q('256f'))
xlog
Logarithm base x.
>>> pykx.q.xlog(2, 8)
pykx.FloatAtom(q('3f'))
Meta
attr
Attributes of an object, returns a Symbol Atom or Vector.
The possible attributes are:
code | attribute |
---|---|
s | sorted |
u | unique (hash table) |
p | partitioned (grouped) |
g | true index (dynamic attribute): enables constant time update and access for real-time tables |
>>> pykx.q.attr([1,2,3])
pykx.SymbolAtom(q('`'))
>>> pykx.q.attr(pykx.q('asc 1 2 3'))
pykx.SymbolAtom(q('`s'))
null
Is null.
>>> pykx.q.null(1)
pykx.BooleanAtom(q('0b'))
>>> pykx.q.null(float('NaN'))
pykx.BooleanAtom(q('1b'))
>>> pykx.q.null(None)
pykx.BooleanAtom(q('1b'))
tables
List of tables in a namespace.
>>> pykx.q('exampleTable: ([] a: til 10; b: 10?10)')
pykx.Identity(pykx.q('::'))
>>> pykx.q('exampleTable: ([] a: til 10; b: 10?10)')
pykx.Table(q('
a b
---
0 8
1 1
2 9
3 5
4 4
5 6
6 6
7 1
8 8
9 5
'))
>>> pykx.q.tables('.')
pykx.SymbolVector(q(',`exampleTable'))
type
Underlying k type of an object.
>>> pykx.q.type(1)
pykx.ShortAtom(q('-7h'))
>>> pykx.q.type([1, 2, 3])
pykx.ShortAtom(q('0h'))
>>> pykx.q.type(pykx.LongVector([1, 2, 3]))
pykx.ShortAtom(q('7h'))
view
Expression defining a view.
>>> pykx.q('v::2+a*3')
>>> pykx.q('a:5')
>>> pykx.q('v')
pykx.LongAtom(q('17'))
>>> pykx.q.view('v')
pykx.CharVector(q('"2+a*3"'))
views
List views defined in the default namespace.
>>> pykx.q('v::2+a*3')
>>> pykx.q('a:5')
>>> pykx.q('v')
pykx.LongAtom(q('17'))
>>> pykx.q.views()
pykx.SymbolVector(q(',`v'))
Queries
fby
Apply an aggregate to groups.
>>> d = pykx.q('data: 10?10')
pykx.LongVector(pykx.q('4 9 2 7 0 1 9 2 1 8'))
>>> group = pykx.SymbolVector(['a', 'b', 'a', 'b', 'c', 'd', 'c', 'd', 'd', 'c'])
pykx.SymbolVector(pykx.q('`a`b`a`b`c`d`c`d`d`c'))
>>> >>> pykx.q.fby(pykx.q('(sum; data)'), group)
pykx.LongVector(pykx.q('6 16 6 16 17 4 17 4 4 17'))
Sort
asc
Ascending sort.
>>> pykx.q.asc([4, 2, 5, 1, 0])
pykx.LongVector(q('`s#0 1 2 4 5'))
bin
Binary search.
>>> pykx.q.bin([0, 2, 4, 6, 8, 10], 5)
pykx.LongAtom(q('2'))
>>> pykx.q.bin([0, 2, 4, 6, 8, 10], [-10, 0, 4, 5, 6, 20])
pykx.LongVector(q('-1 0 2 2 3 5'))
binr
Binary search right.
>>> pykx.q.binr([0, 2, 4, 6, 8, 10], 5)
pykx.LongAtom(q('3'))
>>> pykx.q.binr([0, 2, 4, 6, 8, 10], [-10, 0, 4, 5, 6, 20])
pykx.LongVector(q('0 0 2 3 3 6'))
desc
Descending sort.
>>> pykx.q.desc([4, 2, 5, 1, 0])
pykx.LongVector(q('5 4 2 1 0'))
differ
Find where list items change value.
>>> pykx.q.differ([1, 1, 2, 3, 4, 4])
pykx.BooleanVector(q('101110b'))
distinct
Unique items of a list.
>>> pykx.q.distinct([1, 3, 1, 4, 5, 1, 2, 3])
pykx.LongVector(q('1 3 4 5 2'))
iasc
Ascending grade.
>>> pykx.q.iasc([4, 2, 5, 1, 0])
pykx.LongVector(q('4 3 1 0 2'))
idesc
Descending grade.
>>> pykx.q.idesc([4, 2, 5, 1, 0])
pykx.LongVector(q('2 0 1 3 4'))
rank
Position in the sorted list.
Where x is a list or dictionary, returns for each item in x the index of where it would occur in the sorted list or dictionary.
>>> pykx.q.rank([4, 2, 5, 1, 0])
pykx.LongVector(q('3 2 4 1 0'))
>>> pykx.q.rank({'c': 3, 'a': 4, 'b': 1})
pykx.LongVector(q('2 0 1'))
xbar
Round y down to the nearest multiple of x.
>>> pykx.q.xbar(5, 3)
pykx.LongAtom(q('0'))
>>> pykx.q.xbar(5, 5)
pykx.LongAtom(q('5'))
>>> pykx.q.xbar(5, 7)
pykx.LongAtom(q('5'))
>>> pykx.q.xbar(3, range(16))
pykx.LongVector(q('0 0 0 3 3 3 6 6 6 9 9 9 12 12 12 15'))
xrank
Group by value.
>>> pykx.q.xrank(3, range(6))
pykx.LongVector(q('0 0 1 1 2 2'))
>>> pykx.q.xrank(4, range(9))
pykx.LongVector(q('0 0 0 1 1 2 2 3 3'))
Table
cols
Column names of a table.
>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame({
... 'time': numpy.array([1, 2, 3, 4], dtype='timedelta64[s]'),
... 'sym':['a', 'a', 'b', 'b'],
... 'p': pykx.LongVector([2, 4, 6, 8])
... })
>>> pykx.q.cols(df)
pykx.SymbolVector(q('`time`sym`p'))
csv
CSV delimiter.
A synonym for "," for use in preparing text for CSV files, or reading them.
>>> pykx.q.csv
pykx.CharAtom(q('","'))
fkeys
Foreign-key columns of a table.
>>> pykx.q('f:([x:1 2 3]y:10 20 30)')
pykx.Identity(q('::'))
>>> pykx.q('t: ([]a:`f$2 2 2; b: 0; c: `f$1 1 1)')
pykx.Identity(q('::'))
>>> pykx.q.fkeys('t')
pykx.Dictionary(q('
a| f
c| f
'))
insert
Insert or append records to a table.
>>> pykx.q('t: ([] a: `a`b`c; b: til 3)')
>>> pykx.q('t')
pykx.Table(q('
a b
---
a 0
b 1
c 2
'))
>>> pykx.q.insert('t', ['d', 3])
>>> pykx.q('t')
pykx.Table(q('
a b
---
a 0
b 1
c 2
d 3
'))
key
Where x is a dictionary (or the name of one), returns its keys.
>>> pykx.q.key({'a': 1, 'b': 2})
pykx.SymbolVector(q('`a`b'))
keys
Get the names of the key columns of a table.
>>> pykx.q['v'] = pykx.KeyedTable(data={'x': [4, 5, 6]}, index=[1, 2, 3])
>>> pykx.q('v')
pykx.KeyedTable(pykx.q('
idx| x
---| -
1 | 4
2 | 5
3 | 6
'))
>>> pykx.q.keys('v')
pykx.SymbolVector(q(',`idx'))
meta
Metadata for a table.
Column | Information |
---|---|
c | column name |
t | data type |
f | foreign key (enums) |
a | attribute |
>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame({
... 'time': np.array([1, 2, 3, 4], dtype='timedelta64[s]'),
... 'sym': ['a', 'a', 'b', 'b'],
... 'p': pykx.LongVector([2, 4, 6, 8])
... })
>>> pykx.q.meta(df)
pykx.KeyedTable(q('
c | t f a
----| -----
time| n
sym | s
p | j
'))
ungroup
Where x is a table, in which some cells are lists, but for any row, all lists are of the same length, returns the normalized table, with one row for each item of a lists.
>>> a = pykx.Table([['a', [2, 3], 10], ['b', [5, 6, 7], 20], ['c', [11], 30]], columns=['s', 'x', 'q'])
>>> a
pykx.Table(pykx.q('
s x q
------------
a (2;3) 10
b (5;6;7) 20
c ,11 30
'))
>>> pykx.q.ungroup(a)
pykx.Table(q('
s x q
-------
a 2 10
a 3 10
b 5 20
b 6 20
b 7 20
c 11 30
'))
upsert
Add new records to a table.
>>> import pandas as pd
>>> df = pd.DataFrame({'sym':['a', 'a', 'b', 'b'], 'p': pykx.LongVector([2, 4, 6, 8])})
>>> pykx.Table(df)
pykx.Table(q('
sym p
-----
a 2
a 4
b 6
b 8
'))
>>> pykx.q.upsert(df, ['c', 10])
>>> pykx.Table(q('
sym p
------
a 2
a 4
b 6
b 8
c 10
'))
xasc
Sort a table in ascending order of specified columns.
>>> import pandas as pd
>>> df = pd.DataFrame({'sym':['a', 'a', 'b', 'b', 'c', 'c'], 'p': pykx.LongVector([10, 4, 6, 2, 0, 8])})
>>> pykx.Table(df)
pykx.Table(q('
sym p
------
a 10
a 4
b 6
b 2
c 0
c 8
'))
>>> pykx.q.xasc('p', df)
pykx.Table(q('
sym p
------
c 0
b 2
a 4
b 6
c 8
a 10
'))
xcol
Rename table columns.
>>> import pandas as pd
>>> df = pd.DataFrame({'sym':['a', 'a', 'b', 'b', 'c', 'c'], 'p': pykx.LongVector([10, 4, 6, 2, 0, 8])})
>>> pykx.Table(df)
pykx.Table(q('
sym p
------
a 10
a 4
b 6
b 2
c 0
c 8
'))
>>> pykx.q.xcol(pykx.SymbolVector(['Sym', 'Qty']), df)
pykx.Table(q('
Sym Qty
-------
a 10
a 4
b 6
b 2
c 0
c 8
'))
>>> pykx.q.xcol({'p': 'Qty'}, df)
pykx.Table(q('
sym Qty
-------
a 10
a 4
b 6
b 2
c 0
c 8
'))
xcols
Reorder table columns.
>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame({
... 'time': np.array([1, 2, 3, 4], dtype='timedelta64[s]'),
... 'sym':['a', 'a', 'b', 'b'],
... 'p': pykx.LongVector([2, 4, 6, 8])
... })
>>> pykx.Table(df)
pykx.Table(q('
time sym p
--------------------------
0D00:00:01.000000000 a 2
0D00:00:02.000000000 a 4
0D00:00:03.000000000 b 6
0D00:00:04.000000000 b 8
'))
>>> pykx.q.xcols(pykx.SymbolVector(['p', 'sym', 'time']), df)
pykx.Table(q('
p sym time
--------------------------
2 a 0D00:00:01.000000000
4 a 0D00:00:02.000000000
6 b 0D00:00:03.000000000
8 b 0D00:00:04.000000000
'))
xdesc
Sorts a table in descending order of specified columns. The sort is by the first column specified, then by the second column within the first, and so on.
>>> import pandas as pd
>>> df = pd.DataFrame({'sym':['a', 'a', 'b', 'b', 'c', 'c'], 'p': pykx.LongVector([10, 4, 6, 2, 0, 8])})
>>> pykx.Table(df)
pykx.Table(q('
sym p
------
a 10
a 4
b 6
b 2
c 0
c 8
'))
>>> pykx.q.xdesc('p', df)
pykx.Table(q('
sym p
------
a 10
c 8
b 6
a 4
b 2
c 0
'))
xgroup
Groups a table by values in selected columns.
>>> import pandas as pd
>>> df = pd.DataFrame({'sym':['a', 'a', 'b', 'b', 'c', 'c'], 'p': pykx.LongVector([10, 4, 6, 2, 0, 8])})
>>> pykx.Table(df)
pykx.Table(q('
sym p
------
a 10
a 4
b 6
b 2
c 0
c 8
'))
>>> pykx.q.xgroup('sym', df)
pykx.KeyedTable(q('
sym| p
---| ----
a | 10 4
b | 6 2
c | 0 8
'))
xkey
Set specified columns as primary keys of a table.
>>> import pandas as pd
>>> df = pd.DataFrame({'sym':['a', 'a', 'b', 'b', 'c', 'c'], 'p': pykx.LongVector([10, 4, 6, 2, 0, 8])})
>>> pykx.Table(df)
pykx.Table(q('
sym p
------
a 10
a 4
b 6
b 2
c 0
c 8
'))
>>> pykx.q.xkey('p', df)
pykx.KeyedTable(q('
p | sym
--| ---
10| a
4 | a
6 | b
2 | b
0 | c
8 | c
'))
Text
like
Whether text matches a pattern.
>>> pykx.q.like('quick', b'qu?ck')
pykx.BooleanAtom(q('1b'))
>>> pykx.q.like('brown', b'br[ao]wn')
pykx.BooleanAtom(q('1b'))
>>> pykx.q.like('quick', b'quickish')
pykx.BooleanAtom(q('0b'))
lower
Shift case to lower case.
>>> pykx.q.lower('HELLO')
pykx.SymbolAtom(q('`hello'))
>>> pykx.q.lower(b'HELLO')
pykx.CharVector(q('"hello"'))
ltrim
Remove leading nulls from a list.
>>> pykx.q.ltrim(b' pykx ')
pykx.CharVector(q('"pykx "'))
md5
Message digest hash.
>>> pykx.q.md5(b'pykx')
pykx.ByteVector(q('0xfba0532951f022133f8e8b14b6ddfced'))
rtrim
Remove trailing nulls from a list.
>>> pykx.q.rtrim(b' pykx ')
pykx.CharVector(q('" pykx"'))
ss
String search.
>>> pykx.q.ss(b'a cat and a dog', b'a')
pykx.LongVector(q('0 3 6 10'))
ssr
String search and replace.
>>> pykx.q.ssr(b'toronto ontario', b'ont', b'x')
pykx.CharVector(q('"torxo xario"'))
string
Cast to string.
>>> pykx.q.string(2)
pykx.CharVector(q(',"2"'))
>>> pykx.q.string([1, 2, 3, 4, 5])
pykx.List(q('
,"1"
,"2"
,"3"
,"4"
,"5"
'))
trim
Remove leading and trailing nulls from a list.
>>> pykx.q.trim(b' pykx ')
pykx.CharVector(q('"pykx"'))
upper
Shift case to upper case.
>>> pykx.q.upper('hello')
pykx.SymbolAtom(q('`HELLO'))
>>> pykx.q.upper(b'hello')
pykx.CharVector(q('"HELLO"'))