первый пост о переполнении стека. Я пытаюсь получить представление о том, как найти наиболее подходящие значения из списков и столбцов таблицы с помощью Power Query.
Так что, если у вас есть список {1.1, 3.2, 4.5, 6.6, 7.8} и вы ищете «4.6», то возвращается «4.5».
Очевидно, в Power Query нет встроенных функций, которые делают то, что мне нужно. Я искал сценарий, но подходы, которые приводят к желаемому результату, обычно включают вычитание значения поиска из каждого значения в списке ссылок, преобразование результатов в абсолютные различия и затем возвращение минимума. Вы должны сделать несколько дополнительных шагов, чтобы получить исходное значение. Та же самая техника сделана и на стороне DAX.
Я хочу сопоставить, скажем, 1000+ значений в списке из 50000+ значений, так что это может занять довольно много времени каждый раз, когда запрос обновляется, делая это с абсолютной разницей.
Я искал вокруг и не мог найти двоичный поиск в M, поэтому я написал следующий. Кажется, что это работает и значительно повышает производительность, но я хотел знать, есть ли лучший подход, который кто-либо нашел. Я читал, что использование функции List.Generate () предпочтительнее рекурсии в M, но не понимаю, почему.
/*
Performs a binary search for a number within a sorted list
Function returns a number
*/
let
funcLookup = (myList as list, myNum as number) =>
let
n = List.Count(myList),
n_2 = Number.RoundUp(n/2,0), //Do not use Number.IntegerDivide()
newDiffSign = Number.Sign(myNum - myList{n_2}), //Pos = 1, Neg = -1, Zero = 0
A = if newDiffSign = 1 and n > 1 then List.Range(myList, n_2, n-n_2) //Second half of the list
else if newDiffSign = -1 and n > 1 then List.Range(myList, 0, n_2) //First half of the list
else {myList{n_2}}, //Return the matched number, as a list
//Recursively iterate to winnow the list to 1 number which will be the closest match
Match = if n > 1
then @funcLookup(A, myNum)
else myList{0}
in
Match
in
funcLookup
-----
Я вызываю вышеупомянутую функцию, используя это:
listMyList = List.Buffer(List.Sort(MyTable[MyColumn])), //sorts and buffers the list in memory
MyNewTable = Table.AddColumn(MyTable, "Matched Value", each funcLookUp(listMyList, [MyColumn]))