簡體   English   中英

Power BI 比較不同列和不同行

[英]Power BI comparing different columns with different rows

您好,我有下表:

Date/time 1                   Date/time 2
1/1/2021  12:00:01 PM         1/1/2021  12:00:10 PM
1/1/2021  12:00:08 PM         1/1/2021  12:00:50 PM
1/1/2021  12:00:35 PM         1/1/2021  12:01:40 PM
1/1/2021  12:02:03 PM         1/1/2021  12:02:08 PM

我需要一個將返回以下數據的新列

column 3                   
1/1/2021  12:00:01 PM       
1/1/2021  12:00:01 PM      
1/1/2021  12:00:01 PM      
1/1/2021  12:02:03 PM        

換句話說,它應該是日期/時間 1 的最小值,只要日期/時間 1 < 比上一行中的日期/時間 2 長。 一旦日期/時間 1 大於前一個日期/時間 2,那么它應該重復相同的序列並取最小日期/時間 1,直到它大於前一個日期/時間 2。

我該如何進行呢? 我對使用 power query 或 dax 的解決方案持開放態度

這些操作在電源查詢上下文中並不是很簡單。 這並不是說它不能完成,但我認為 go 最簡單的方法是在 Python 的幫助下。

Power BI 支持在表上運行 python 腳本,將表拉入 pandas 數據幀。 然后您可以在 Python 中對其進行操作,並將所需結果存儲在另一個 dataframe 中。 然后,您可以將其解壓縮回電源查詢表! 下面是您的 python 代碼的代碼片段!

蟒蛇剪斷

現在,這絕不是在 python 中執行此操作的最優雅的方式,但它在語法上很短並且很有效並且很容易理解。

您可以從電源查詢編輯器添加 python 腳本,方法是轉到轉換選項卡並選擇 python 圖標

您的 python 代碼中的任何 dataframe 都可以提取到 power Bi 中的表中

您可以使用行級別來獲取最短日期時間。 在創建列的那一刻,您可以訪問行級別,並使用List.Min獲取最小值。 忽略Source步驟,這只是為了重現您的數據。 解決方案在步驟NewColumn上。

電源查詢代碼

let
  Source = Table.FromRows(
    Json.Document(
      Binary.Decompress(
        Binary.FromText(
          "i45WMjDUByIjAyNDBUMjKwMDKwNDJR1MUUMDpVgdbKotsKk2xaHa2BRTtaGVCVbVQGSMqdoIZGNsLAA=", 
          BinaryEncoding.Base64
        ), 
        Compression.Deflate
      )
    ), 
    let
      _t = ((type nullable text) meta [Serialized.Text = true])
    in
      type table [#"Date/time 1" = _t, #"Date/time 2" = _t]
  ), 
  NewColumn = Table.AddColumn(
    Source, 
    "Min DateTime", 
    (row) => List.Min({row[#"Date/time 1"], row[#"Date/time 2"]})
  )
in
  NewColumn

Output

日期/時間 1 日期/時間 2 最小日期時間
2021 年 1 月 1 日 12:00:01 2021 年 1 月 1 日 12:00:10 2021 年 1 月 1 日 12:00:01
2021 年 1 月 1 日 12:00:08 2021 年 1 月 1 日 12:00:50 2021 年 1 月 1 日 12:00:08
2021 年 1 月 1 日 12:00:35 2021 年 1 月 1 日 12:01:40 2021 年 1 月 1 日 12:00:35
2021 年 1 月 1 日 12:02:03 2021 年 1 月 1 日 12:02:08 2021 年 1 月 1 日 12:02:03

原始表

日期/時間 1 日期/時間 2
2021 年 1 月 1 日 12:00:01 2021 年 1 月 1 日 12:00:10
2021 年 1 月 1 日 12:00:08 2021 年 1 月 1 日 12:00:50
2021 年 1 月 1 日 12:00:35 2021 年 1 月 1 日 12:01:40
2021 年 1 月 1 日 12:02:03 2021 年 1 月 1 日 12:02:08

這似乎符合您的要求:通過添加一個與Date/Time 2偏移一的列,我們使比較更簡單(並且這種方法比使用索引列更快)

let
    Source = Excel.CurrentWorkbook(){[Name="Table7"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Date/Time 1", type datetime}, {"Date/Time 2", type datetime}}),

//add an offset column relative to column2
    prevRow = Table.FromColumns(
        Table.ToColumns(#"Changed Type") & {{null} & List.RemoveLastN(#"Changed Type"[#"Date/Time 2"])}, 
        type table [#"Date/Time 1" = datetime, #"Date/Time 2" = datetime, prevRow=datetime]),

//add custom column with "the test"
    #"Added Custom" = Table.AddColumn(prevRow, "Custom", each 
        if [prevRow] = null then [#"Date/Time 1"] else 
            if [#"Date/Time 1"] < [prevRow] then null else [#"Date/Time 1"], type datetime),

//remove unneeded column and fill down the custom column
    #"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"prevRow"}),
    #"Filled Down" = Table.FillDown(#"Removed Columns",{"Custom"})
in
    #"Filled Down"

在此處輸入圖像描述

使用DAX

如果你有這樣的桌子

| Index | Date/time 1          | Date/time 2          |
|-------|----------------------|----------------------|
| 1     | 1/1/2021 12:00:01 PM | 1/1/2021 12:00:10 PM |
| 2     | 1/1/2021 12:00:08 PM | 1/1/2021 12:00:50 PM |
| 3     | 1/1/2021 12:00:35 PM | 1/1/2021 12:01:40 PM |
| 4     | 1/1/2021 12:02:03 PM | 1/1/2021 12:02:08 PM |
| 5     | 1/1/2021 12:02:06 PM | 1/1/2021 12:02:10 PM |
| 6     | 1/1/2021 12:02:04 PM | 1/1/2021 12:02:12 PM |

您可以編寫以下兩個措施來達到您的目標

_lastNonBlank =
VAR _index =
    MAX ( _tbl[Index] )
VAR _preceding = _index - 1
VAR _dt1 =
    MAX ( _tbl[Date/time 1] )
VAR _dt2 =
    CALCULATE (
        MAX ( _tbl[Date/time 2] ),
        FILTER ( ALLSELECTED ( _tbl ), _tbl[Index] = _preceding )
    )
VAR _lastNonBlank =
    IF ( _dt1 > _dt2, _index )
RETURN
    _lastNonBlank


_dt1 =
VAR _index =
    MAX ( _tbl[Index] )
RETURN
    CALCULATE (
        MAX ( _tbl[Date/time 1] ),
        FILTER (
            ALLSELECTED ( _tbl ),
            _tbl[Index] <= _index
                && [_lastNonBlank] <> BLANK ()
        )
    )

S1

僅使用 1 行代碼的方法將如下所示。 它在速度和 memory 方面的效率有點低,但是如果您的數據集不是太大,它應該可以正常工作。

1:通過在電源查詢編輯器的查詢部分右鍵單擊它來復制您的表。 在重復的表中,使用 group by,刪除建議的聚合,並 select min 和 Date/Time 1 作為您的列。 該表現在只包含日期/時間 1 的最小值。將值為 1 的列添加到最小值表(稍后會有意義)

2:在您的原始表中,從添加列選項卡添加一個索引列。 然后還添加一個作為該索引 +1 的列。 現在使用合並查詢,執行 left 類型的自連接(將表與自身合並),其中您匹配索引 +1 上的表的索引。 (另一種方法是再次復制表然后合並)

3:合並后,擴展添加的查詢和 select 僅日期/時間 2 的列(使用左外連接)並將其重命名為 prevtime2 (或任何你喜歡的)

4:添加一個值為 1 的列,並使用合並查詢在包含第一步中最小值的表上連接表,使用兩個表中包含一個的列(這基本上是完全無條件的全外連接)。 展開包含最小值的列並將其重命名為 MinDateTime 之類的名稱。

5:添加這樣的自定義列

在此處輸入圖像描述

一切就緒(盡管您可能仍需要手動處理第一行,但 rest 應該不錯!)

可能看起來有很多步驟,但您實際上可以很快完成。 一旦您選擇了步驟 5 的結果,您就可以刪除所有其他不需要的列。您最終會在 model 中得到 1/2 個額外的表(取決於您是否使用了自聯接),但您可以隱藏它們或者給他們起個好名字,這樣他們就不會被使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM