Forum Discussion
Faster Division/Multiplication using Merge same table Query - Power Query
- 5 years ago
Hello Anonymous
here some dynamic solution. Uses Unpivoting, Grouping and twice transforming of columns. The only parameter you have to change is the list in the Unpivot other (in case you have some additional columns). As you can see you can also remove the column "count" from your table.
let Origine = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("VVRLdiQxCLtLr/PmGTD+XGGWs+3X979GCgmYZNFWUiVTIMl+v1/y+nr9+/snYPqziM5ndXuWHf/Hz4a+Pl/vl5IbMIOwVryMxfez3OenIqAaqQEaz2VE2Rmf2bHhxAs/4E5yAzTezVg0tlo8k9gkc4Dr5Hq9dKmyGm1J7JLFHha5aBLtWn3BT3OvgbvJ3VXI0cio4uCvDeoh9VQL14rq3a4aFbvk3uKu/stHj3Ypg4y0IlB3CYHWp1YTT2Mgl2+BFm/3aP2gBMw8TnY6B+R8Ud+8XAd5TZLTO6DGmwMvbtkOP+8lOc0DmtSIVHlU0ycrp3tA5GxpVUYvGF02rZb0D4g5EUi0gPbx/FJoSQOB2mlWqSihD0ml00KgjoqRjdISOslM8dJEoMaWNcpFq9zLYmlNE7XdsFNnAElCRCzJaSK7hHiz+qWJ8iPOWsdPO9BSwtlp9s7a6aIy5T1jH1mmiVJrughE/eWlha3/jTB7mjYCIcjxX2niERg0XdNGIHOxah9Snuc7204fgdqRg3SYGTuch1bTR9bqWEvH5Hfp9JH30SzDKaeXj0JFLH0ESgeUI+/OE0e09BGIULHyqYmZp2Knj9YXFu4N6DxnnwLnbWN1k1pn9VZLuHQ4TZLTRyDMZEpPpapueJDTRg4WX1+7Io0jiRF3Vk4XgT8uJ6lv7B8nxtJEoPa9jm2ME8xRxsnSRWa4O+cipUfe05Ym8s6It94XMfSmeHlkZroIhDGzXURzZD8KfD7f", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ID = _t, CD = _t, #"6" = _t, #"5" = _t, #"4" = _t, #"3" = _t, #"1" = _t, Count = _t]), ChangeType = Table.TransformColumnTypes(Origine,{{"6", Int64.Type}, {"5", Int64.Type}, {"4", Int64.Type}, {"3", Int64.Type}, {"1", Int64.Type}}), #"Removed Columns" = Table.RemoveColumns(ChangeType,{"Count"}), #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Removed Columns", {"ID", "CD"}, "Attribute", "Value"), #"Grouped Rows" = Table.Group(#"Unpivoted Other Columns", {"CD"}, {{"AllRows", each _, type table [ID=text, CD=text, Attribute=text, Value=number]}}), TransformAllRows = Table.TransformColumns ( #"Grouped Rows", { { "AllRows", (tbl)=> let SumValue = List.Sum(tbl[Value]), TransformTbl = Table.TransformColumns ( tbl, { { "Value", each _ / SumValue } } ) in TransformTbl } } ), #"Expanded AllRows" = Table.ExpandTableColumn(TransformAllRows, "AllRows", {"ID", "Attribute", "Value"}, {"ID", "Attribute", "Value"}), #"Pivoted Column" = Table.Pivot(#"Expanded AllRows", List.Distinct(#"Expanded AllRows"[Attribute]), "Attribute", "Value", List.Sum), #"Changed Type" = Table.TransformColumnTypes(#"Pivoted Column",{{"ID", Int64.Type}}), #"Sorted Rows" = Table.Sort(#"Changed Type",{{"ID", Order.Ascending}}) in #"Sorted Rows"Copy paste this code to the advanced editor in a new blank query to see how the solution works.
If this post helps or solves your problem, please mark it as solution (to help other users find useful content and to acknowledge the work of users that helped you)
Kudoes are nice too
Have fun
Jimmy
I found Anonymous solution quite innovative with the calculations done in lists. However, the solution loses other main columns like CD, ID etc and you have to again rename the Attrb columns.
Jimmy801 solution was straight forward with the unpivot - pivot and calculations though it took the same amount of time as my solution.
The problem that i am facing is that i am adding additional calculated columns to this final table and at each step that references previous calculated step, the loading just increases exponentially into Gigabytes though only for these 40 rows.
for e.g.
1. Step1 = Table.AddColumn(Step0, each [6] / Average[6]) then
2. Step2 = Table.AddColumn(Step1, each [4] / Average[4]).
But that will be another post that i will put up today.
Hi Anonymous
" ...
I found @Rocco_sprmnt21 solution quite innovative with the calculations done in lists. However, the solution loses other main columns like CD, ID etc and you have to again rename the Attrb columns.
..."
I have tried, from what can be understood from the request, to stay strictly on the subject and give a hopefully useful suggestion.
I haven't tried to do a school homework with all the things in the right place: I don't have enough time to do this right now.
If from a performance point of view my solution is preferable to the others that work at the row level, you could fill in the missing aspects.
- Anonymous5 years agoNot applicable
From the title of the subject it seemed an important aspect, but I'm not sure if that's the case.
However, I wanted to propose a comparison between the performances of the different solutions.
This calculates the percentages of the row total for a 10 X 1,000,000 table less than 5 'let dim=1000000, lst = List.Transform({1..10}, each List.Transform(List.Random(dim, _), each Number.Round(_*dim,0))), tfo= Table.FromColumns(lst), #"Aggiunta colonna indice" = Table.AddIndexColumn(tfo, "Indice", 1, 1, Int64.Type), tab = Table.AddColumn(#"Aggiunta colonna indice", "CD", each "RJ."& Text.From([Indice])), Origine = tab, #"Rimosse colonne" = Table.RemoveColumns(Origine,{"Indice"}), #"Trasformate altre colonne tramite UnPivot" = Table.UnpivotOtherColumns(#"Rimosse colonne", {"CD"}, "Attributo", "Valore"), #"Rimosse colonne1" = Table.RemoveColumns(#"Trasformate altre colonne tramite UnPivot",{"Attributo"}), #"Colonna trasformata tramite Pivot" = Table.Pivot(#"Rimosse colonne1", List.Distinct(#"Rimosse colonne1"[CD]), "CD", "Valore", (v)=>List.Transform(v, each _/List.Sum(v))), #"Trasposta colonna" = Table.FromRows(Table.Transpose(#"Colonna trasformata tramite Pivot")[Column1]) in #"Trasposta colonna"this ("yours") seems much faster
let dim=1000000, Origine = Table.FromColumns(List.Transform({1..5}, each List.Transform(List.Random(dim, _), each Number.Round(_*dim,0))),{"6","5","4","3","1"}), #"Aggiunta colonna personalizzata" = Table.AddColumn(Origine, "Counts", each [6]+[5]+[4]+[3]+[1]), #"Changed Type" = Table.TransformColumnTypes(#"Aggiunta colonna personalizzata",{{"6", Int64.Type}, {"5", Int64.Type}, {"4", Int64.Type}, {"3", Int64.Type}, {"1", Int64.Type}, {"Counts", Int64.Type}}), PercentOfRow = Table.FromRecords( Table.TransformRows( #"Changed Type", (r) => Record.TransformFields( r, { {"6", each r[#"6"] / r[Counts] }, {"5", each r[#"5"] / r[Counts] }, {"4", each r[#"4"] / r[Counts] }, {"3", each r[#"3"] / r[Counts] }, {"1", each r[#"1"] / r[Counts] } } ) ), type table [ #"6" = Percentage.Type, #"5" = Percentage.Type, #"4" = Percentage.Type, #"3" = Percentage.Type, #"1" = Percentage.Type ] ) in PercentOfRow- Anonymous5 years agoNot applicable
A more coincise and (peraphs ) general way to write "your" code:
let dim=1000000, Origine = Table.FromColumns(List.Transform({1..10}, each List.Transform(List.Random(dim, _), each Number.Round(_*dim,0))),{"0".."9"}), PercentOfRow = Table.FromRecords( Table.TransformRows(Origine, (r)=> let sum=List.Sum(Record.FieldValues(r)) in Record.FromList(List.Transform(Record.FieldValues(r), each _/sum), {"0".."9"})& [Counts=sum])), pc = Table.TransformColumnTypes(PercentOfRow,List.Transform(Table.ColumnNames(Origine),each {_, Percentage.Type})) in pc - Anonymous5 years agoNot applicable
Interesting Anonymous !
The main problem with my solution or yours or Jimmy801 is that when i start adding custom calculated columns (row-level evaluation) to our final table, the loading time just keeps on increasing exponentially. 😞
for e.g. if i add the following calculated columns to our final table:
Step1 = AddColumn(Final, "Total" , each [#"6"] + [#"4"], Percentage.Type) RowAvgOfTotal = Number.Round(List.Average(Step1[Total]), 2) Step2 = AddColumn(Step1, "Total%" , each [Total] / RowAvgOfTotal, Percentage.Type) RowPercentileOfTotal = Number.Round(PercentileInclusive(Step2[Total%], 0.8), 4 ) Step3 = AddColumn(Step2, "Total%Percentile" , each [Total] / RowPercentileOfTotal, Percentage.Type)PercentileInclusive Function:
//PercentileInclusive Function let Source = (inputSeries as list, percentile as number) => let SeriesCount = List.Count(inputSeries), PercentileRank = percentile*(SeriesCount-1)+1, //percentile value between 0 and 1 PercentileRankRoundedUp = Number.RoundUp(PercentileRank), PercentileRankRoundedDown = Number.RoundDown(PercentileRank), Percentile1 = List.Max(List.MinN(inputSeries,PercentileRankRoundedDown)), Percentile2 = List.Max(List.MinN(inputSeries,PercentileRankRoundedUp)), Percentile = Percentile1+(Percentile2-Percentile1)*(PercentileRank-PercentileRankRoundedDown) in Percentile in SourceAdding such calculated columns just increases loading time from 4 to 5mbs to gb's. It is apparent that adding the columns to previous steps each time increases the load time as i think the previous calculated columns are also getting evaluated again. Any alternative approach that you can suggest?
- Anonymous5 years agoNot applicable
I'm not sure I understand what you want to do, but maybe it can be useful to try doing separate calculations on the same source table and then putting it all together.
ac1 = func1 (tab),
ac2 = func2 (tab),
..tfc=Table.FromColumns(