Страницы: 1
RSS
Мера: разница между датами
 
Привет всем,

Помогите пожалуйста с таким вопросом.
Есть таблица данных. В одном столбце есть повторяющиеся значения c "номером транспорта", в другом столбце "дата", не повторяющиеся для конкретного номера транспорта и другие столбы.
1. Нужно средствами Power Query убрать дубликаты по строкам где повторяются одновременно "Номер транспорта", "Дата", "Код" - это я сделал через удаление дубликата ключа, в котором объединил столбцы. Может быть есть более элегантный способ.
2. Нужно средствами Power Pivot создать меру, которая будет считать средний оборот рейса транспорта как среднее разницы между ближайшими датами по совпадающему номеру транспорта.

Заранее спасибо за помощь.
Изменено: mikhailkhv - 06.02.2024 12:33:16
 
в PQ удалить дубликаты строк можно не объединяя предварительно. просто выделите нужные столбцы перед удалением дубликатов
 
Цитата
mikhailkhv написал:
Может быть есть более элегантный способ.
Код
Table.Distinct(Источник, {"Номер транспорта", "Дата", "Код"})

Цитата
mikhailkhv написал:
как разницу между датами
у вас кол-во дат от 1 до 5. И как тогда считать эту вашу разницу между датами?
Изменено: AlienSx - 06.02.2024 12:27:57
Пришелец-прораб.
 
Цитата
написал:
у вас кол-во дат от 1 до 5. И как тогда считать эту вашу разницу между датами?
Добрый день!
Я поправил в описании проблемы. Я хочу посчитать меру "Средний оборот Транспорта" как среднее разницы между ближайшими датами по совпадающему номеру транспорта начиная с наименьшей даты, заканчивая наибольшей.
Я думаю это можно реализовать как разницу между максимальной и минимальной датой у одного и того же номера транспорта разделить на кол-во повторений в таблице без дубликатов - (минус) 1 (во вложении сделал через формулы excel).
Но мне кажется, если я в исходном файле захочу посмотреть оборот поквартально (оригинальный массив за год), то у меня будет искажение меры, нежели если считать в лоб через разницу ближайших дат.
Заранее спасибо!
 
mikhailkhv, с DAX я вам, скажу сразу, не помощник. Но со стороны вся эта движуха выглядит как-то странно. Такое впечатление, что или транспорт все время в рейсах или не хватает дат начала и окончания рейса. Если вы потом захотите фильтровать даты (за квартал, например), то какие даты должны участвовать в расчете? Вообщем, все не так просто, как вы описываете, как мне кажется. Как написал выше, по DAX я не помогу, но пожелаю удачи.
Пришелец-прораб.
 
mikhailkhv, можно добавить столбец, где будет последующая дата по этому транспорту к текущей дате. последняя дата будет всегда "null", или напишите значение по условию. тогда можно рассчитывать разницу и делать фильтры по столбцу с первой датой.
ну мне так кажется)
Код
let
    fr = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
    a0 = List.Buffer(Table.ColumnNames(fr)),
    a1 = Table.Distinct(fr, a0),
    f =(x)=> [  z0 = Table.ToColumns(Table.Sort(x, a0{1})),
                z1 = List.Skip(z0{1}),
                z2 = Table.FromColumns(z0&{z1}, a0&{"Дата2"})],
    a2 = Table.Group(a1, a0{0}, {"Date", (x)=>f(x)[z2]})[Date],
    to = Table.Combine(a2)
in
    to
 
Garrys,
Спасибо большое!
Попробовал ваше решение, но почему-то оно подходит только для первого рейса.
Например для второй рейса "40018962" с 15.01.2023 по 27.01.2023 во второй дате значение получается null (см. вложение).

Если не сложно, не могли бы объяснить что за магия происходит тут?))
Цитата
написал:
f =(x)=> [  z0 = Table.ToColumns(Table.Sort(x, a0{1})),
               z1 = List.Skip(z0{1}),
               z2 = Table.FromColumns(z0&{z1}, a0&{"Дата2"})],
   a2 = Table.Group(a1, a0{0}, {"Date", (x)=>f(x)[z2]})[Date],
Upd: вроде разобрался, надо было определить тип данных и все заработало, но вопрос про магию все еще актуален)
Изменено: mikhailkhv - 07.02.2024 17:15:10
 
mikhailkhv, тут добавляется столбец дат с удалением первой. но проблема в другом: у вас мешанина в номерах - то число, то текст. либо приведите входные данные в порядок, либо измените тип столбца на текстовый при группировке - Table.TransformColumnTypes(a1,{a0{0}, Text.Type})
 
Garrys,
Спасибо за ответ!
На массиве до 100 тыс строк из 6 фитчей (столбцы) работает отлично!
Но на 1 миллионе строк (данные за 2 месяцев) и 12 фитчах обработка данных занимает часа 2.
Я же хочу обработать данные за 2 года ~ 12 млн строк. Один раз уже запускал, но за сутки мой компьютер не справился.
Как думаете можно оптимизировать Ваше решение для PQ, или пора переходить на питон?)
Заранее спасибо!  
 
mikhailkhv, а может сразу на DAX без обработки в PQ. Попробуйте вариант во вложении на своем 1млн строк, хотя он тоже далек от оптимальности  
 
mikhailkhv, можете залить файл на 1 млн например на яндекс-диск и дать ссылку?
 
Garrys,
Залил сюда. Спасибо!
https://disk.yandex.ru/d/5W0123d8F71sGw

Alex,
Спасибо большое!
Решение работает намного быстрее, чем PQ!)
Но когда я хочу сгруппировать оборот по коду или по месяцам, но выдает не верный результат, потому что мера считает только по массиву группировки (см. пример на яндекс-диске).
 
mikhailkhv, дело конечно Ваше, но вы уверены что у Вас правильный расчет в Таблице от Garrys, возьмем, например номер машины 40003527, он у Вас показывает оборот в январе 61, что влияет на итог января, хотя если смотреть даты то поездка была в период с января по март и моя мера данную поездку не учитывает для января, соответственно оборот и меньше по сравнению с таблицей от Garrys
 
Alex,
Да, в том то и дело, в вашем примере я бы хотел видеть все рейсы которые начались в январе, а завершится они могут в любую другую дату.
В любом случае спасибо за предложенное решение.
Осталось понять как оно работает)
 
mikhailkhv,  так в том то и дело, что Вам нужно определиться с методикой расчета, т.к. в январе 31 день, а средний оборот по указанной Выше машине 61. А меру поправить, чтоб совпали итоги с таблицей, то пожалуйста, замените в мере  [ДниВПути]  код на следующий
Код
=var Tab = CALCULATETABLE(SUMMARIZE('Test2';'Test2'[Номер транспорта];'Test2'[Дата отправления]);ALLEXCEPT('Test2';Test2[Номер транспорта]))
var CurDate = MAX('Test2'[Дата отправления])
var NextDate = MINX( FILTER(Tab;'Test2'[Дата отправления]>CurDate);'Test2'[Дата отправления])
var Dif = IF(ISBLANK(NextDate); BLANK(); NextDate- CurDate)
return INT(Dif)
 
mikhailkhv, по методике расчета показателей думайте сами, код по загрузке из 3 файлов прикладываю, основной посыл - делайте Table.Distinct в таблицах с небольшим количеством строк (внутри группировки). у меня из всех файлов в модель загрузилось минут за 5
Код
let
//собираем все файлы в таблицу
    fold = Table.SelectRows(Folder.Contents(" Ваша папка с файлами "), (x)=> not Text.StartsWith(x[Name], "~")),
    f1 =(x)=> Table.SelectRows(Table.TransformColumnTypes(Excel.Workbook(x, true){[Item = "Лист1"]}[Data], {"Номер транспорта", Text.Type}), (y)=>y[Номер транспорта]<>"0"),
    fr = Table.Combine(List.Transform(fold[Content], f1)), 
//обрабатываем
    nm = List.Buffer(Table.ColumnNames(fr)),
    f2 =(x)=> [ z1 = Table.Sort(Table.Distinct(x, {nm{0}, nm{1}, nm{2}}), nm{1}),
                z11 = if Table.RowCount(z1)=1 then #table(nm, {}) else z1,
                z2 = Table.ToColumns(z11),
                z3 = List.Skip(z2{1}),
                z4 = Table.RemoveLastN(Table.FromColumns(z2&{z3}, nm&{"Дата2"}),1),
                z5 = Table.AddColumn(z4, "Оборот", (x)=>Duration.Days(x[Дата2]-x[Дата отправления]))][z5],
    a1 = Table.Group(fr, nm{0}, {"new", (x)=>f2(x)}),
    a2 = Table.Combine(a1[new])
in
    a2
 
Alex, Garrys,
Спасибо вам больше за помощь!
Скиньте номер кошелька в ЛС, с удовольствием угощу вас пивом)
Страницы: 1
Наверх