KDB +: форматирование значений в таблицах - PullRequest
0 голосов
/ 26 сентября 2018

Какой самый надежный способ задать правила для форматирования значений таблицы?Я хочу применить каждое правило к соответствующему столбцу наиболее эффективным способом.Я полагаю, что в этом случае было бы полезно использовать функциональную форму.

Вот пример таблицы:

tbl:flip `GARP`longWgt`shortWgt`longWgtBeta`shortWgtBeta`longWgtRisk`shortWgtRisk`netWgt`netExposure`relativeBeta`relativeRisk`adjBeta`adjRisk!(`GARP_AUTOS_CA`GARP_BANKS_CA`GARP_CHEMICALS_CA`GARP_COMMUNICATIONS_CA`GARP_CONS_DISCR_CA;0.0091686 0.0176234 0.0076484 0.0131509 0.0460397;-0.010305 -0.0470135 0n -0.0078549 -0.0563819;1.3522162 0.6234817 1.3140238 0.7327634 1.1802914;0.1440806 0.7642193 0n 0.7216727 0.6112765;0.3254744 0.1573925 0.2541326 0.2554008 0.350877;0.3079491 0.2218098 0n 0.2594863 0.2758658;-0.0011365 -0.0293902 0.0076484 0.005296 -0.0103422;0.8897173 0.374857 0n 1.67422 0.8165681;9.3851363 0.8158414 0n 1.0153681 1.9308631;1.0569097 0.7095833 0n 0.9842553 1.2719117;8.3501184 -3.269856 0n 1.6999496 1.5766812;-1.0634328 -3.7595078 0n 1.64786 1.0386025)

Я хочу, чтобы во всех столбцах были 2 значащих цифры.Столбцы longWgt, shortWgt and netWgt должны быть в процентах.

У меня есть что-то подобное, но я уверен, что есть лучший способ сделать это:

tbl:update longWgt:100f*longWgt, shortWgt:100f*shortWgt, netWgt:100f*netWgt from tbl;
tbl:update .Q.f[2] each longWgt, .Q.f[2] each shortWgt, .Q.f[2] each longWgtBeta, .Q.f[2] each shortWgtBeta, .Q.f[2] each longWgtRisk, .Q.f[2] each shortWgtRisk, .Q.f[2] each netWgt, .Q.f[2] each netExposure, .Q.f[2] each relativeBeta, .Q.f[2] each relativeRisk, .Q.f[2] each adjBeta, .Q.f[2] each adjRisk from tbl;
tbl:update {x,"%"} each longWgt, {x,"%"} each shortWgt, {x,"%"} each netWgt from tbl;

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Вы также можете использовать форму с тремя аргументами оператора @ apply, который можно найти здесь https://code.kx.com/wiki/Reference/AtSymbol, поскольку вы применяете функции только к столбцам, а не агрегируете, фильтруете или переименовываете любые столбцы.

Он индексирует в элемент, указанный в первом аргументе со вторым аргументом, а затем применяет функцию в третьем аргументе к результирующим элементам, оставляя другие элементы нетронутыми.

@[`tbl;wgtCols;100*];
@[`tbl;allCols;.Q.f[2]'];
@[`tbl;wgtCols;{x,'"%"}];

Их можно легко объединитьв одну функцию, используя каждый из них ', который будет перебирать список аргументов, применяя их по очереди.Информацию о каждом из них можно найти https://code.kx.com/q/ref/adverbs/#each-both

@[`tbl;;]'[(wgtCols;allCols;wgtCols);(100*;.Q.f[2]';{x,'"%"})]]

Все они будут исправлены на месте, например, перезаписать переменную tbl.Если вы не хотите, чтобы это происходило, вы можете использовать эту функцию:

@[;;]/[tbl;(wgtCols;allCols;wgtCols);(100*;.Q.f[2]';{x,'"%"})]

При этом используется оператор / (сканирование) для применения каждой функции по очереди, причем первая функция работает с исходной таблицей ирезультаты передаются в следующую функцию.

0 голосов
/ 26 сентября 2018

Как насчет использования функционального запроса :

Сначала умножьте wgtCols ниже на 100:

wgtCols: `longWgt`shortWgt`netWgt;
![`tbl;();0b;wgtCols!{(*;100f;x)} each wgtCols];

Затем отформатируйте все столбцы allColsкроме `GARP с двумя десятичными знаками:

allCols:1_cols tbl;
![`tbl;();0b;allCols!{(each;.Q.f[2];x)} each allCols];

Наконец, отформатируйте wgtCols в процентный формат:

![`tbl;();0b;wgtCols!{(each;{x,"%"};x)} each wgtCols]

Примечание: чтобы узнать, как создать функциональный запрос, выможно использовать оператор parse для q-запроса по вашему выбору:

parse "update longWgt:100f*longWgt, shortWgt:100f*shortWgt, netWgt:100f*netWgt from tbl"

Вывод:

!
`tbl
()
0b
`longWgt`shortWgt`netWgt!((*;100f;`longWgt);(*;100f;`shortWgt);(*;100f;`netWgt))
...