Страницы: 1
RSS
Power Query - умножение каждого значения по условию в одном из столбцов
 
Доброй ночи.
Пробовал сделать по аналогии с предыдущим вопросом, но что-то совсем не получается.

Вот данные:

Код
let  
      Source = #table(   
        {"NAME", "TRUE/FALSE", "HER", "Number 1", "Number 2"},    
          {     
              {"A", "383","AS","1", "10"},     
              {"C", "384","AV","2", "15"},
              {"V", "385","AS","2", "20"},
              {"B", "383","AZ","5", "80"}, 
              {"S", "384","AZ","1", "30"},     
              {"Q", "383","AS","6", "60"},
              {"E", "385","AZ","7", "70"},
              {"R", "384","AV","5", "12"},   
              {"T", "383","AV","4", "14"},     
              {"P", "384","AS","6", "99"} 
          }
      )
in  
      Source


Надо обратить внимание, что они приходят именно в текстовом виде.
Колонок с числами, аналогичных колонке 4 и 5 больше (60), но идут подряд.
В зависимости от значения в колонке 2 требуется умножить каждое число из колонок 4, 5...60 на число.
А число исчисляется так:
Код
f10x = (x) => Number.Power(10, (Number.FromText(x)-383)*3)


Если проще... то 383 - не умножаем число, 384 - умножаем на 1000, 385 - умножаем на миллион и т.д.
Но вот заменять значения во второй колонке нельзя.

Иначе говоря, таблица должна приобрести вот такой вид:


Код
let  
      Source = #table(   
        {"NAME", "TRUE/FALSE", "HER", "Number 1", "Number 2"},    
          {     
              {"A", "383","AS",1, 10},     
              {"C", "384","AV",2000, 15000},
              {"V", "385","AS",2000000, 20000000},
              {"B", "383","AZ",5, 80}, 
              {"S", "384","AZ",1000, 30000},     
              {"Q", "383","AS",6, 60},
              {"E", "385","AZ",7000000, 70000000},
              {"R", "384","AV",5000, 12000},   
              {"T", "383","AV",4, 14},     
              {"P", "384","AS",6000, 99000} 
          }
      )
in  
      Source


Надеюсь не пропустил ничего.
Спасибо за помощь.


P.S. Не могу никак начать мыслить в синтаксисе PQ.
Изменено: Kirill Gureev - 07.03.2021 01:32:13
 
del
Изменено: buchlotnik - 23.08.2021 15:30:15
Соблюдение правил форума не освобождает от модераторского произвола
 
Доброе время суток.
Ещё вариант.
Код
let
    Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
    changeColumns = List.Range(Table.ColumnNames(Source), 3),
    addMult = Table.AddColumn(Source, "mult", each Number.Power(10, (Number.FromText([#"TRUE/FALSE"]) - 383) * 3)),
    replace = Table.ReplaceValue(addMult, each _, null, (s, o, n) => s * o[mult], changeColumns),
    removeTempColumn = Table.RemoveColumns(replace,{"mult"})
in
    removeTempColumn
По времени - так же как и у Алексея. На базовых "383".."389"
Изменено: Андрей VG - 07.03.2021 08:27:32
 
del
Изменено: buchlotnik - 23.08.2021 15:30:03
Соблюдение правил форума не освобождает от модераторского произвола
 
Цитата
buchlotnik написал:
именно в текстовом виде
Привет, Михаил.
Не проблема - чуть меняем шаг
Код
replace = Table.ReplaceValue(addMult, each _, null, (s, o, n) => Number.From(s) * o[mult], changeColumns)

P. S. Table.ReplaceValue забавно себя ведёт, если в функции ошибка - просто оставляет прежнее значение, а не пишет ошибку.
Изменено: Андрей VG - 07.03.2021 11:13:38
 
Цитата
Андрей VG написал:
чуть меняем шаг
не, так отрабатывает долго, чуть более шустрый см предыдущее сообщение
Соблюдение правил форума не освобождает от модераторского произвола
 
Цитата
buchlotnik написал:
так отрабатывает долго
Ну, не знаю. Вот тестовый набор, оба два на моём ноуте чуть быстрее 5 секунд (Excel 365 64 бит 2102 (сборка 13801.20266).
Изменено: Андрей VG - 07.03.2021 11:18:36
 
скорость сильно зависит от исходных данных, на тестовом наборе вышло так (свой брал из #4):
Соблюдение правил форума не освобождает от модераторского произвола
 
Цитата
buchlotnik написал:
скорость сильно зависит от исходных данных
Это, да. Проблема варианта Алексея в том, что при слишком большом наборе TRUE/FALSE выборка строк даёт заметные тормоза. Михаил, большое спасибо за контрольное исследование.
Изменено: Андрей VG - 07.03.2021 12:13:41
 
ну да, если работать с 383-386 имеем
Соблюдение правил форума не освобождает от модераторского произвола
 
Михаил, а такой вариант?
Код
let
    Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
    changeColumns = List.Buffer(List.Range(Table.ColumnNames(Source), 3)),
    typed = Table.TransformColumnTypes(Source, List.Transform(changeColumns, each {_, Number.Type})),
    addMult = Table.AddColumn(typed, "mult", each Number.Power(10, (Number.FromText([#"TRUE/FALSE"]) - 383) * 3)),
    replace = Table.TransformRows(addMult, (rec) as record =>
        Record.TransformFields(rec, List.Transform(changeColumns, each {_, (x) => rec[mult] * x}))
    ),
    result = Table.FromRecords(replace),
    removeTempColumn = Table.RemoveColumns(result, {"mult"})
in
    removeTempColumn
У меня на моём наборе на секунду быстрее.
 
Цитата
Андрей VG написал:
на секунду быстрее
да, есть такое:

короче на записях всё равно быстрее получается
Соблюдение правил форума не освобождает от модераторского произвола
 
buchlotnik,  не получается повторить этот код:
Скрытый текст


Моя загвоздка в строке:
Код
  lst = List.Transform(List.Distinct(from[m]),(x)=>{x,Number.Power(10, (Number.FromText(x)-383)*3)}),


Я не могу понять что такое "m"! Оно от куда взялось?!
 
Цитата
Kirill Gureev написал:
Я не могу понять что такое "m"
можно открыть файл и посмотреть
Соблюдение правил форума не освобождает от модераторского произвола
 
БОЖЕ! Где этот файл то? Не вижу вложений ни в одно сообщение!
 
а, ну да, мы ж тут на 10k тестим - не влезают - это столбец [#"TRUE/FALSE"] - я его переименовал;

пы.сы. а почему вы решили взять самый медленный из предложенных вариантов?
Соблюдение правил форума не освобождает от модераторского произвола
 
Меня смутило "Загоняние в буфер" , у строк несколько миллиардов... я вот очень переживаю по этому поводу.
 
Цитата
Kirill Gureev написал:
Загоняние в буфер
т.е. разобраться с тем, ЧТО загоняется в буфер не вариант? как знаете... начинали с 60, а оказывается миллиарды
Изменено: buchlotnik - 08.03.2021 00:15:11
Соблюдение правил форума не освобождает от модераторского произвола
 
Данный форум меня научил ставить мини-задачи, чтобы  быстро находить решения.
В итоге передумал, взял Ваш вариант - самый быстрый, суда по тестам.
Запустил просчёт.... поскольку таблиц 10, то решение получим часов через 5 (с учётом всез дополнительных преобразований).

Спасибо большое за помощь!
Я очень стараюсь научиться.
 
Цитата
Kirill Gureev написал:
то решение получим часов через 5 (с учётом всез дополнительных преобразований).
Однако! По тестам для 60 столбцов скорость 3000 строк в секунду
5 * 3600 * 3000 = 54 000 000
Пусть у вас столбцов только 10, считаем зависимость линейной от числа столбцов, тогда
54 000 000 * 6 = 324 000 000.
Цитата
Kirill Gureev написал:
строк несколько миллиардов
Следовательно, вы в расчётах скорости выполнения промахнулись на порядок :)
 
с такими объемами даже не VBA, C++ нужен... тайминги вот тут весьма красноречивы
Изменено: buchlotnik - 08.03.2021 00:52:54
Соблюдение правил форума не освобождает от модераторского произвола
 
30 часов? Ну не))
 
Цитата
Kirill Gureev написал:
30 часов?
Загрузка из текстового файла на 10 столбцов с целыми числами идёт в модель данных со скоростью чуть более 100 тысяч строк в секунду. Соответственно, 1 миллиард строк 8,3 часа. Несколько это три и более, следовательно, только загрузка займёт 25 часов. Если Excel и Power Pivot сможет это проглотить.
 
Я делаю в Power BI. Надеемся на него)
 
Цитата
Kirill Gureev написал:
Power BI. Надеемся на него
Судя по этой статье Power BI limit - напрасно.
Цитата
Row limit - the maximum number of rows in your dataset (when not using DirectQuery) is 2 billion, with three of those rows reserved (resulting in a usable maximum of 1,999,999,997 rows)
Что меньше 2 миллиардов. Конечно, можете надеяться, что с 2018 года ограничения были увеличены.
 
Всё получается. Спасибо.
Страницы: 1
Наверх