1. 程式人生 > 實用技巧 >按總期數為每期生成獨立行資料(金融應用)

按總期數為每期生成獨立行資料(金融應用)

今天的案例場景是,如下面左圖所示,有標籤列,日期列,期數列,這樣的資料通常出現在一些需要按年月週日持續進行多期的資料裡面,例如週期性合同的執行,銀行還款記錄。

需要將這個資料錶轉換成以下右側效果所示。

整理思路:

要求:我們需要按照期數對原始資料中的每一行進行重複,並且日期需要按照當前的期號來重新確定,第1期的日期等於原始日期,第2期的日期等於第1期日期向後推移1個單位(我這裡是按月來推移,你也可以自行修改成按照其他週期來推移)。

說明:我使用的Office版本是2016,如果你的Office是2013,需要上微軟官網下載PowerQuery的外掛安裝包安裝。

操作實現:

  1. 首先我們將原始資料轉換成表格,並且命名為”data”,至於如何將資料區域轉換成表,請讀者自己百度解決,結果如下圖。

  2. 依次選擇選單“資料/獲取和轉換/從表格”將資料匯入Power Query中;
  3. 進入Power Query介面後,我們首先給原始資料data表新增一個索引列,因為原始資料中的標籤列不一定是非重複的,我們新增一個索引來唯一標識行

  4. 接下來我們按照索引、標籤對資料進行分組,分組的目的是為了生成一個子表,這個子表將會按照期數來生成。為了在左側導航窗格中保留原始資料data查詢,我們另起一個空查詢來做這個步驟

  5. 在編輯欄直接輸入如下公式,手動輸入Table.Group函式,可以比Power Query自動生成的公式簡潔,公式的含義就是對data表,按索引、標籤列分組,分組的資料放到名為“子表 ”的列中。
    = Table.Group(data, {"索引", "標籤"}, {{"子表", each _}})

  6. 接下來我們需要對子表的內容進行變換處理,使其從1行資料的表變換出對應期數行數的表,列只需要2列,分別是期號和日期。這裡我們結合使用List.Generate函式和Table.FromList函式來生成這個新的子表。老套路,我們先去微軟官方看下這2個函式的基本結構和說明。

    我們使用List.Generate函式先產生一個元素是Record的List,然後將這個List傳遞給Table.FromList來生成結果表。為了更加清楚的認識List.Generate函式生成單個元素是Record的List的過程,我又新建了一個空查詢,其公式程式碼如下:其效果是生成一個包含9個元素的列表,列表中每個元素都是Record,Record包含2個鍵值對,第一個鍵名為x,第二個鍵名為y,x,y值相同,且列表中每項的值是從1遞增的。

    第一個引數:函式,指定列表結果起始項的資料

    第二個引數:函式,指定列表生成的結束條件,這裡我指定當x鍵的值<10時就生成項,否則就終止生成

    第三個引數:函式,指定除了列表第1項外,其餘項的生成規則,我這裡是將x和y的對應值+1,也就是實現遞增1

    第四個引數:函式,指定對最終生成的結果列表進行篩選的方式,我這裡不需要進行篩選處理,所以直接取所有資料,直接使用_符號表示

    = List.Generate(
        () => [x = 1, y = 1],
        each [x] < 10,
        each [x = [x]+1, y = [y]+1],
        each _)

  7. Table.FromList函式我就不再加以詳細說明,不清楚的話可以參考微軟官方說明中示例理解。接下來就在編輯欄中輸入如下的公式,這裡我已經對公式進行了格式化的處理,以便能更清楚的理解計算實現過程,相比較於前面第5步中的公式,我們變動了子表的生成程式碼。
    = Table.Group(data, {"索引","標籤"}, {
        {"子表", 
            (t)=>Table.FromList(
                List.Generate(
                    ()=>[期號=1,日期=t{0}[日期]],
                    each [期號]<=t{0}[期數],
                    each [期號=[期號]+1,日期=Date.AddMonths([日期],1)],
                    each _
                ),
                Record.FieldValues,
                {"期號","日期"}
            )
        }
    })

    首先我們來看List.Generate函式生成列表的過程

    第一個引數:列表起始項的期號為1,日期從分組完畢的子表第1行的日期列取值

    第二個引數:當期號的值小於等於子表中的期數值時,可以繼續生成列表項

    第三個引數:除了列表第1項外,其餘項的生成規則是,期號遞增1,日期是上一個日期向後遞增1個月

    第四個引數:最終生成的結果列表不進行篩選,直接返回整個列表

    然後我們再來看Table.FromList函式生成表的過程

    第一個引數:表,就是我們使用List.Generate函式生成的列表

    第二個引數:Record.FieldValues,指定分隔符是按欄位(需要第一個引數中的列表中的每個項是一個Record)

    第三個引數:指定生成後的表,其表頭的名稱

    此時,我們得到的結果如下所示

  8. 接下來我們就需要將子表中的內容展開

  9. 將日期列的資料型別轉換為日期

  10. 最後將結果上載到Excel中即可