Skip to content

Registering Custom Operations

The purpose of this functionality is to provide an extension mechanism for PyKX allowing users to register extension logic for PyKX.

Specifically this allows users to:

  1. Extend the supported conversions from Pythonic types to PyKX objects when using the pykx.toq function
  2. Extend the supported custom functions on pykx.Column objects

pykx.register

Functionality for the registration of conversion functions between PyKX and Python

py_toq

py_toq(py_type, conversion_function, *, overwrite=False)

Register conversion logic for a specified Python type when converting it to a PyKX object.

Note

The return of registered functions should be a valid pykx object type returns of Pythonic types can result in unexpected errors

Warning

Application of this functionality is at a users discretion, issues arising from overwritten default conversion types are unsupported

Parameters:

Name Type Description Default
py_type Any

The type signature used for determining when a conversion should be triggered for PyKX, in particular this will check the type(x) on incoming data to determine this.

required
conversion_function Callable

The function/callable which will be used to convert the supplied object to a PyKX object specified by the user.

required
overwrite bool

If a definition for this type already exists should it be overwritten by default this is set to False to avoid accidental overwriting of conversion logic used within the library

False

Returns:

Type Description
None

A None object on successful invocation

Examples:

Register conversion logic for complex Python object types

>>> import pykx as kx
>>> kx.toq(complex(1, 2))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pykx/toq.pyx", line 2543, in pykx.toq.ToqModule.__call__
  File "pykx/toq.pyx", line 245, in pykx.toq._default_converter
TypeError: Cannot convert <class 'complex'> '(1+2j)' to K object
>>> def complex_toq(data):
...    return kx.toq([data.real, data.imag])
>>> kx.register.py_toq(complex, complex_toq)
>>> kx.toq(complex(1, 2))
pykx.FloatVector(pykx.q('1 2f'))

Register conversion logic for complex Python objects overwriting previous logic above

>>> def complex_toq_upd(data):
...    return kx.q('{`real`imag!(x;y)}', kx.toq(data.real), kx.toq(data.imag)
>>> kx.register.py_toq(complex, complex_toq_upd, overwrite=True)
>>> kx.toq(complex(1, 2))
pykx.Dictionary(pykx.q('
real| 1
imag| 2
'))
>>>

column_function

column_function(name, conversion_function, overwrite=False)

Register a function to be accessible as a callable function off the kx.Column objects

Note

The return of this function should be a QueryPhrase object

Warning

Application of this functionality is at a users discretion, issues arising from overwritten default conversion types are unsupported

Parameters:

Name Type Description Default
name str

The name to be given to the method which can be used on a column

required
conversion_function Callable

The function/callable which will be applied when calling a query

required

Returns:

Type Description
None

A None object on successful invocation

Examples:

Register min-max scaler function for application on column

>>> import pykx as kx
>>> tab = kx.Table(data = {
...     'sym': kx.random.random(100, ['a', 'b', 'c']),
...     'true': kx.random.random(100, 100.0),
...     'pred': kx.random.random(100, 100.0)
... })
>>> def min_max_scaler(self):
...     return self.call('{(x-minData)%max[x]-minData:min x}')
>>> kx.register.column_function('minmax', min_max_scaler)
>>> tab.select(kx.Column('true') & kx.Column('true').minmax().rename('scaled_true'))

Register mean-absolute error function to be applied between 'true' and 'pred' columns

>>> import pykx as kx
>>> tab = kx.Table(data = {
...     'sym': kx.random.random(100, ['a', 'b', 'c']),
...     'true': kx.random.random(100, 100.0),
...     'pred': kx.random.random(100, 100.0)
... })
>>> def mean_abs_error(self, other):
...     return self.call('{avg abs x-y}', other)
>>> kx.register.column_function('mean_abs_error', mean_abs_error)
>>> tab.exec(kx.Column('pred').mean_abs_error(kx.Column('true')))
>>> tab.select(kx.Column('pred').mean_abs_error(kx.Column('true')), by=kx.Column('sym'))