The ultimate Fabric, Power BI, SQL, and AI community-led learning event. Save €200 with code FABCOMM.
Get registeredCompete to become Power BI Data Viz World Champion! First round ends August 18th. Get started.
Hi all, I am trying to build a simple moving average for a table containing 500 stocks and daily data for multiple years. I have built a small test set with 3 stocks with 2 years of data. Some 1500 rows only. I am getting results but the time it takes and MBs it takes is exploding already on this test. Code below. All runs quick and flawless untill list.average. Removing non necessary columns does not help. Tried a few other methods but all with similar slow result. Any help is appreciated.
let
Source = Excel.Workbook(File.Contents("C:\test.xlsx"), null, true),
Table1_Table = Source{[Item="Table1",Kind="Table"]}[Data],
#"Changed Type" = Table.TransformColumnTypes(Table1_Table,{{"ticker", type text}, {"date", type date}, {"open", type number}, {"high", type number}, {"low", type number}, {"close", type number}, {"volume", Int64.Type}, {"dividend", type number}, {"split", Int64.Type}, {"adj_open", type number}, {"adj_high", type number}, {"adj_low", type number}, {"adj_close", type number}, {"adj_volume", Int64.Type}}),
#"Sorted Rows" = Table.Sort(#"Changed Type",{{"ticker", Order.Ascending}, {"date", Order.Ascending}}),
#"Grouped Rows" = Table.Group(#"Sorted Rows", {"ticker"}, {{"Count", each _, type table [ticker=nullable text, date=nullable date, open=nullable number, high=nullable number, low=nullable number, close=nullable number, volume=nullable number, dividend=nullable number, split=nullable number, adj_open=nullable number, adj_high=nullable number, adj_low=nullable number, adj_close=nullable number, adj_volume=nullable number]}}),
#"Added Index" = Table.AddIndexColumn(#"Grouped Rows", "tickerIndex", 1, 1, Int64.Type),
#"Removed Columns" = Table.RemoveColumns(#"Added Index",{"ticker"}),
#"Expanded Count" = Table.ExpandTableColumn(#"Removed Columns", "Count", {"ticker", "date", "open", "high", "low", "close", "volume", "dividend", "split", "adj_open", "adj_high", "adj_low", "adj_close", "adj_volume"}, {"ticker", "date", "open", "high", "low", "close", "volume", "dividend", "split", "adj_open", "adj_high", "adj_low", "adj_close", "adj_volume"}),
#"Grouped ticker" = Table.Group(#"Expanded Count", {"ticker"}, {{"Details", each _, type table [ticker=nullable text, date=nullable date, open=nullable number, high=nullable number, low=nullable number, close=nullable number, volume=nullable number, dividend=nullable number, split=nullable number, adj_open=nullable number, adj_high=nullable number, adj_low=nullable number, adj_close=nullable number, adj_volume=nullable number, tickerIndex=nullable number]}}),
#"Added dateIndex" = Table.AddColumn(#"Grouped ticker", "TableWithDateIndex", each Table.AddIndexColumn([Details], "DateIndex", 1, 1, Int64.Type)),
#"Removed Columns1" = Table.RemoveColumns(#"Added dateIndex",{"ticker", "Details"}),
#"Expanded TableWithDateIndex" = Table.ExpandTableColumn(#"Removed Columns1", "TableWithDateIndex", {"ticker", "date", "open", "high", "low", "close", "volume", "dividend", "split", "adj_open", "adj_high", "adj_low", "adj_close", "adj_volume", "tickerIndex", "DateIndex"}, {"ticker", "date", "open", "high", "low", "close", "volume", "dividend", "split", "adj_open", "adj_high", "adj_low", "adj_close", "adj_volume", "tickerIndex", "DateIndex"}),
#"Added Index1" = Table.AddIndexColumn(#"Expanded TableWithDateIndex", "Index", 1, 1, Int64.Type),
#"Added Custom" = Table.AddColumn(#"Added Index1", "Custom", each #"Added Index1"),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom.1", each [Custom][adj_close]),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "Custom.2", each if [DateIndex] < 3 then null else List.Range([Custom.1], [Index] - 3, 3)),
#"Removed Columns2" = Table.RemoveColumns(#"Added Custom2",{"Custom", "Custom.1"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Removed Columns2",{{"ticker", type text}, {"date", type date}, {"open", type number}, {"high", type number}, {"low", type number}, {"close", type number}, {"volume", Int64.Type}, {"dividend", Int64.Type}, {"split", Int64.Type}, {"adj_open", type number}, {"adj_high", type number}, {"adj_low", type number}, {"adj_close", type number}, {"adj_volume", Int64.Type}, {"tickerIndex", Int64.Type}, {"DateIndex", Int64.Type}, {"Index", Int64.Type}, {"Custom.2", type any}}),
#"Added Custom3" = Table.AddColumn(#"Changed Type1", "Custom", each List.Average([Custom.2]))
in
#"Added Custom3"
Hi,
Check if a DAX measure runs faster.
Hi, @Jan-Jaap72
According to your M code , it seems you want to get the average of the previous_3_row values in for the [adj_close] column.
And for your M code , you create mult-table and columns in it .
For your need , you can try to use this M code to see if there is a improvement for performance.
let
Source = Excel.Workbook(File.Contents("C:\test.xlsx"), null, true),
Table1_Table = Source{[Item="Table1",Kind="Table"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Table1_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"ticker", type text}, {"date", type date}, {"open", type number}, {"high", type number}, {"low", type number}, {"close", type number}, {"volume", Int64.Type}, {"dividend", type number}, {"split", Int64.Type}, {"adj_open", type number}, {"adj_high", type number}, {"adj_low", type number}, {"adj_close", type number}, {"adj_volume", Int64.Type}}),
Custom1 = Table.Group(#"Changed Type","ticker",{"test",(x)=> Table.AddIndexColumn( x, "Index", 1, 1, Int64.Type) }),
#"Expanded test" = Table.ExpandTableColumn(Custom1, "test", {"date", "open", "high", "low", "close", "volume", "dividend", "split", "adj_open", "adj_high", "adj_low", "adj_close", "adj_volume", "Index"}, {"date", "open", "high", "low", "close", "volume", "dividend", "split", "adj_open", "adj_high", "adj_low", "adj_close", "adj_volume", "Index"}),
#"Added Custom" = Table.AddColumn(#"Expanded test", "Custom", (x)=>
try List.Average( List.Range(#"Expanded test"[adj_close],x[Index]-3,3)) otherwise null
)
,
#"Changed Type1" = Table.TransformColumnTypes(#"Added Custom",{{"date", type date}, {"open", type number}, {"high", type number}, {"low", type number}, {"close", type number}, {"volume", Int64.Type}, {"dividend", type number}, {"split", Int64.Type}, {"adj_open", type number}, {"adj_high", type number}, {"adj_low", type number}, {"adj_close", type number}, {"adj_volume", Int64.Type}, {"Custom", type number}, {"Index", Int64.Type}})
in
#"Changed Type1"
Then we can get this in the Power Query Editor:
And also we can keep the Index column and apply the data to the Desktop and we can click "New Column" to create a calculated column :
Column = var _t = FILTER('Query1' , 'Query1'[ticker] = EARLIER('Query1'[ticker]) && 'Query1'[Index]<=EARLIER(Query1[Index]) && 'Query1'[Index]>EARLIER(Query1[Index])-3)
return
AVERAGEX(_t ,[adj_close])
We can also get this in Desktop:
If this method does not meet your needs, you can provide us with your special sample data and the desired output sample data in the form of tables, so that we can better help you solve the problem. (You can also upload you sample .pbix [without sensitive data] to the OneDrive and share with the OneDrive link to me ! )
Thank you for your time and sharing, and thank you for your support and understanding of PowerBI!
Best Regards,
Aniya Zhang
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly
Thank you Aniya for your reply. I tested your code and learning from it. The output is good, but it remains as slow as before. I also have tried Table.Buffer, also didn't help sofar. Please see attached a data sample of 3 tickers and 10 days of data (i am normally testing with 500 days of data which already makes it very very slow). Eventually I am using close to 10 years of data, and over 500 tickers.
ticker | date | open | high | low | close | volume | dividend | split | adj_open | adj_high | adj_low | adj_close | adj_volume |
A | 2020-01-02 | 85.9 | 86.35 | 85.2 | 85.95 | 1410486 | 0 | 1 | 84.08 | 84.52 | 83.39 | 84.13 | 1410486 |
A | 2020-01-03 | 84.67 | 85.33 | 84.5 | 84.57 | 1118322 | 0 | 1 | 82.87 | 83.52 | 82.71 | 82.78 | 1118322 |
A | 2020-01-06 | 84 | 84.82 | 83.6 | 84.82 | 1992491 | 0 | 1 | 82.22 | 83.02 | 81.83 | 83.02 | 1992491 |
A | 2020-01-07 | 83.96 | 85.26 | 83.94 | 85.08 | 1722896 | 0 | 1 | 82.18 | 83.45 | 82.16 | 83.28 | 1722896 |
A | 2020-01-08 | 85.96 | 86.47 | 85.2 | 85.92 | 1847585 | 0 | 1 | 84.14 | 84.64 | 83.39 | 84.1 | 1847585 |
A | 2020-01-09 | 86.46 | 87.7 | 86.17 | 87.27 | 1912699 | 0 | 1 | 84.63 | 85.84 | 84.34 | 85.42 | 1912699 |
A | 2020-01-10 | 87.72 | 88.24 | 87.32 | 87.59 | 1417028 | 0 | 1 | 85.86 | 86.36 | 85.47 | 85.73 | 1417028 |
A | 2020-01-13 | 87.81 | 88.32 | 86.74 | 87.46 | 1630160 | 0 | 1 | 85.95 | 86.45 | 84.9 | 85.61 | 1630160 |
A | 2020-01-14 | 87.27 | 88.21 | 86.7 | 87.99 | 1675243 | 0 | 1 | 85.42 | 86.34 | 84.86 | 86.12 | 1675243 |
A | 2020-01-15 | 87.63 | 89.11 | 87.55 | 88.62 | 1630364 | 0 | 1 | 85.77 | 87.22 | 85.69 | 86.74 | 1630364 |
AAL | 2020-01-02 | 28.98 | 29.3 | 28.65 | 29.09 | 6275633 | 0 | 1 | 28.88 | 29.19 | 28.55 | 28.99 | 6275633 |
AAL | 2020-01-03 | 28.27 | 28.29 | 27.34 | 27.65 | 14020066 | 0 | 1 | 28.17 | 28.19 | 27.24 | 27.55 | 14020066 |
AAL | 2020-01-06 | 27.19 | 27.49 | 27.08 | 27.32 | 6008794 | 0 | 1 | 27.09 | 27.39 | 26.99 | 27.22 | 6008794 |
AAL | 2020-01-07 | 27.56 | 27.68 | 27.06 | 27.22 | 6197079 | 0 | 1 | 27.46 | 27.58 | 26.97 | 27.12 | 6197079 |
AAL | 2020-01-08 | 27.1 | 28.09 | 27.07 | 27.84 | 10497296 | 0 | 1 | 27.01 | 27.99 | 26.98 | 27.74 | 10497296 |
AAL | 2020-01-09 | 28.09 | 28.23 | 27.71 | 27.95 | 6870153 | 0 | 1 | 27.99 | 28.13 | 27.61 | 27.85 | 6870153 |
AAL | 2020-01-10 | 27.96 | 27.99 | 27.25 | 27.32 | 8108419 | 0 | 1 | 27.86 | 27.89 | 27.15 | 27.22 | 8108419 |
AAL | 2020-01-13 | 27.32 | 27.53 | 27.16 | 27.39 | 5841463 | 0 | 1 | 27.22 | 27.43 | 27.06 | 27.29 | 5841463 |
AAL | 2020-01-14 | 27.91 | 28.4 | 27.35 | 27.53 | 8890948 | 0 | 1 | 27.81 | 28.3 | 27.25 | 27.43 | 8890948 |
AAL | 2020-01-15 | 27.45 | 28.06 | 27.32 | 27.58 | 5689926 | 0 | 1 | 27.35 | 27.96 | 27.22 | 27.48 | 5689926 |
AAP | 2020-01-02 | 160.47 | 160.95 | 157.53 | 159.41 | 944940 | 0 | 1 | 149.49 | 149.94 | 146.75 | 148.5 | 944940 |
AAP | 2020-01-03 | 158.03 | 159.63 | 157.25 | 159.42 | 566975 | 0 | 1 | 147.22 | 148.71 | 146.49 | 148.51 | 566975 |
AAP | 2020-01-06 | 157.74 | 158.89 | 156.43 | 156.8 | 879926 | 0 | 1 | 146.95 | 148.02 | 145.73 | 146.07 | 879926 |
AAP | 2020-01-07 | 156.9 | 157.4 | 152.41 | 154.94 | 1132189 | 0 | 1 | 146.17 | 146.63 | 141.98 | 144.34 | 1132189 |
AAP | 2020-01-08 | 154.85 | 156.05 | 153.14 | 153.16 | 825747 | 0 | 1 | 144.26 | 145.37 | 142.66 | 142.68 | 825747 |
AAP | 2020-01-09 | 153.78 | 153.98 | 150.25 | 152.87 | 1177403 | 0 | 1 | 143.26 | 143.45 | 139.97 | 142.41 | 1177403 |
AAP | 2020-01-10 | 153.18 | 153.5 | 148.61 | 149.01 | 1416121 | 0 | 1 | 142.7 | 143 | 138.44 | 138.82 | 1416121 |
AAP | 2020-01-13 | 145.33 | 147 | 142.76 | 145.26 | 2138699 | 0 | 1 | 135.39 | 136.94 | 132.99 | 135.32 | 2138699 |
AAP | 2020-01-14 | 145.59 | 149.08 | 144.34 | 148.9 | 1568390 | 0 | 1 | 135.63 | 138.88 | 134.47 | 138.71 | 1568390 |
AAP | 2020-01-15 | 149.58 | 151.49 | 147.82 | 150.21 | 1208806 | 0 | 1 | 139.35 | 141.13 | 137.71 | 139.93 | 1208806 |
Hi , @Jan-Jaap72
Thanks for your quick response!
According to your description, your current loading speed is still very slow. I'm so sorry, I've tried my best to help you reduce the steps in Power Query. You can try dropping unneeded columns before calculating to see if that improves performance.
And also you can try to use the dax to replace the M code .
Column 2 = RANKX( FILTER('Query1','Query1'[ticker]=EARLIER(Query1[ticker])) , CALCULATE( MAX('Query1'[date]),ALLEXCEPT('Query1','Query1'[date]) ) , [date],ASC,Dense)
Thank you for your time and sharing, and thank you for your support and understanding of PowerBI!
Best Regards,
Aniya Zhang
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly
Thank you Aniya for your reply. I tested your code and learning from it. The output is good, but it remains as slow as before. I also have tried Table.Buffer, also didn't help sofar. Please see attached a data sample of 3 tickers and 10 days of data (i am normally testing with 500 days of data which already makes it very very slow). Eventually I am using close to 10 years of data, and over 500 tickers.
ticker | date | open | high | low | close | volume | dividend | split | adj_open | adj_high | adj_low | adj_close | adj_volume |
A | 2020-01-02 | 85.9 | 86.35 | 85.2 | 85.95 | 1410486 | 0 | 1 | 84.07880746 | 84.51926687 | 83.39364837 | 84.12774739 | 1410486 |
A | 2020-01-03 | 84.67 | 85.33 | 84.5 | 84.57 | 1118322 | 0 | 1 | 82.87488507 | 83.5208922 | 82.70848929 | 82.7770052 | 1118322 |
A | 2020-01-06 | 84 | 84.82 | 83.6 | 84.82 | 1992491 | 0 | 1 | 82.21908995 | 83.02170487 | 81.82757047 | 83.02170487 | 1992491 |
A | 2020-01-07 | 83.96 | 85.26 | 83.94 | 85.08 | 1722896 | 0 | 1 | 82.179938 | 83.4523763 | 82.16036203 | 83.27619253 | 1722896 |
A | 2020-01-08 | 85.96 | 86.47 | 85.2 | 85.92 | 1847585 | 0 | 1 | 84.13753538 | 84.63672271 | 83.39364837 | 84.09838343 | 1847585 |
A | 2020-01-09 | 86.46 | 87.7 | 86.17 | 87.27 | 1912699 | 0 | 1 | 84.62693472 | 85.8406451 | 84.3430831 | 85.41976166 | 1912699 |
A | 2020-01-10 | 87.72 | 88.235 | 87.32 | 87.59 | 1417028 | 0 | 1 | 85.86022107 | 86.3643024 | 85.4687016 | 85.73297724 | 1417028 |
A | 2020-01-13 | 87.81 | 88.32 | 86.7384 | 87.46 | 1630160 | 0 | 1 | 85.94831296 | 86.44750029 | 84.89943228 | 85.60573341 | 1630160 |
A | 2020-01-14 | 87.27 | 88.21 | 86.7 | 87.99 | 1675243 | 0 | 1 | 85.41976166 | 86.33983243 | 84.86184641 | 86.12449672 | 1675243 |
A | 2020-01-15 | 87.63 | 89.11 | 87.55 | 88.62 | 1630364 | 0 | 1 | 85.77212919 | 87.22075125 | 85.6938253 | 86.74113989 | 1630364 |
AAL | 2020-01-02 | 28.98 | 29.295 | 28.65 | 29.09 | 6275633 | 0 | 1 | 28.87842271 | 29.19231861 | 28.54957939 | 28.98803715 | 6275633 |
AAL | 2020-01-03 | 28.27 | 28.29 | 27.34 | 27.65 | 14020066 | 0 | 1 | 28.17091132 | 28.19084122 | 27.24417105 | 27.55308447 | 14020066 |
AAL | 2020-01-06 | 27.19 | 27.4901 | 27.08 | 27.32 | 6008794 | 0 | 1 | 27.09469681 | 27.39374494 | 26.98508237 | 27.22424115 | 6008794 |
AAL | 2020-01-07 | 27.56 | 27.68 | 27.06 | 27.22 | 6197079 | 0 | 1 | 27.46339993 | 27.58297932 | 26.96515247 | 27.12459166 | 6197079 |
AAL | 2020-01-08 | 27.1 | 28.09 | 27.07 | 27.84 | 10497296 | 0 | 1 | 27.00501227 | 27.99154224 | 26.97511742 | 27.74241851 | 10497296 |
AAL | 2020-01-09 | 28.09 | 28.23 | 27.71 | 27.95 | 6870153 | 0 | 1 | 27.99154224 | 28.13105152 | 27.61287417 | 27.85203295 | 6870153 |
AAL | 2020-01-10 | 27.96 | 27.99 | 27.25 | 27.32 | 8108419 | 0 | 1 | 27.8619979 | 27.89189274 | 27.15448651 | 27.22424115 | 8108419 |
AAL | 2020-01-13 | 27.32 | 27.53 | 27.155 | 27.39 | 5841463 | 0 | 1 | 27.22424115 | 27.43350508 | 27.05981949 | 27.29399579 | 5841463 |
AAL | 2020-01-14 | 27.91 | 28.4 | 27.35 | 27.53 | 8890948 | 0 | 1 | 27.81217315 | 28.30045566 | 27.254136 | 27.43350508 | 8890948 |
AAL | 2020-01-15 | 27.45 | 28.06 | 27.32 | 27.58 | 5689926 | 0 | 1 | 27.35378549 | 27.96164739 | 27.22424115 | 27.48332983 | 5689926 |
AAP | 2020-01-02 | 160.47 | 160.95 | 157.53 | 159.41 | 944940 | 0 | 1 | 149.4922233 | 149.9393864 | 146.7533492 | 148.5047381 | 944940 |
AAP | 2020-01-03 | 158.03 | 159.63 | 157.25 | 159.42 | 566975 | 0 | 1 | 147.2191441 | 148.7096878 | 146.492504 | 148.514054 | 566975 |
AAP | 2020-01-06 | 157.74 | 158.89 | 156.4325 | 156.8 | 879926 | 0 | 1 | 146.948983 | 148.0203114 | 145.7309293 | 146.0732886 | 879926 |
AAP | 2020-01-07 | 156.9 | 157.4 | 152.409 | 154.94 | 1132189 | 0 | 1 | 146.1664476 | 146.6322425 | 141.9826775 | 144.3405314 | 1132189 |
AAP | 2020-01-08 | 154.85 | 156.05 | 153.14 | 153.16 | 825747 | 0 | 1 | 144.2566884 | 145.3745962 | 142.6636697 | 142.6823015 | 825747 |
AAP | 2020-01-09 | 153.78 | 153.98 | 150.25 | 152.87 | 1177403 | 0 | 1 | 143.2598872 | 143.4462052 | 139.971375 | 142.4121405 | 1177403 |
AAP | 2020-01-10 | 153.18 | 153.5 | 148.61 | 149.01 | 1416121 | 0 | 1 | 142.7009333 | 142.9990421 | 138.4435677 | 138.8162036 | 1416121 |
AAP | 2020-01-13 | 145.33 | 147 | 142.76 | 145.26 | 2138699 | 0 | 1 | 135.387953 | 136.943708 | 132.9937671 | 135.3227417 | 2138699 |
AAP | 2020-01-14 | 145.59 | 149.08 | 144.34 | 148.9 | 1568390 | 0 | 1 | 135.6301663 | 138.8814149 | 134.465679 | 138.7137287 | 1568390 |
AAP | 2020-01-15 | 149.58 | 151.49 | 147.82 | 150.21 | 1208806 | 0 | 1 | 139.3472098 | 141.1265465 | 137.7076117 | 139.9341115 | 1208806 |