【问题标题】:Transforming data using Python Pandas (or M) in Power Query for PowerBi在 Power Query for PowerBi 中使用 Python Pandas(或 M)转换数据
【发布时间】:2022-12-14 17:59:25
【问题描述】:

我有一些关于项目的数据,我想以一种更容易使用 PowerBi 进行分析的方式进行转换。

数据如下所示:

Project Number Project Name Planned Start Date SM1 SM2 SM3
10000 A Apr-21 10 20 30
10001 B Jun-21 40 50 60
10002 C Sep-22 70 80 90

所谓的“SavingMonths”是与项目绩效相对应的值,每个顺序列代表基于项目开始日期的下个月。

例如,项目 A 于 2021 年 4 月开始,因此 SavingsMonth1=April-21,SavingsMonth2=May-21... 等等。

我想以这种格式获取它:

这样,我现在可以按日期过滤/总结“储蓄”列。

我不是程序员,但我知道一些Python 并认为 Pandas 库可能有所帮助,但我才刚刚开始学习它。我根本不知道 M,但我意识到我可以在 Power Query 中使用 Python 进行转换,这很好。

【问题讨论】:

  • 这是一个公平的问题,但您能否将您的数据复制/粘贴为文本,而不是图像。
  • 我已经编辑了,希望更好

标签: python pandas dataframe powerbi powerquery


【解决方案1】:

回答这个问题的人大多是正确的,除了递增的月份外,这几乎是一个不可逆转的问题。我们可以使用melt 来取消透视,但是我们必须添加一些日期偏移量以使月份正确,然后将它们转换回原始格式。

import pandas as pd
df = pd.DataFrame({'Project Number':[10000,10001,10002],
                   'Project Name':['A','B','C'],
                  'Planned Start Date':['Apr-21','Jun-21','Sep-22'],
                  'SavingsMonth1':[10,40,70],
                  'SavingsMonth2':[20,50,80],
                  'SavingsMonth3':[30,60,90]})


df['Planned Start Date'] = pd.to_datetime('01-'+df['Planned Start Date'])

df.sort_values(by='Planned Start Date', inplace=True)

df = df.melt(id_vars=['Project Number','Project Name', 'Planned Start Date'], value_name='Savings')
df['offset'] = df['variable'].str.extract('(d)').astype(int).sub(1)
df['Planned Start Date'] = (df['Planned Start Date'].dt.to_period('M') + df['offset']).dt.strftime('%b-%y')
df = df.sort_values(by='Project Number').drop(columns=['variable','offset'])


print(df)

输出

  Project Number Project Name Planned Start Date  Savings
0           10000            A             Apr-21       10
3           10000            A             May-21       20
6           10000            A             Jun-21       30
1           10001            B             Jun-21       40
4           10001            B             Jul-21       50
7           10001            B             Aug-21       60
2           10002            C             Sep-22       70
5           10002            C             Oct-22       80
8           10002            C             Nov-22       90

【讨论】:

  • 我认为这个解决方案只需稍作调整就可以为我工作,非常感谢克里斯!您将如何处理计划开始日期中的 NaN?
  • 也许用 1970 年的日期填充它,然后在计算后再次用 NaN 替换 1970 年的日期?很难肯定,有点取决于你的目标
【解决方案2】:

在 powerquery (M) 中,假设日期从文本列开始,此 (a) 逆透视 (b) 将文本转换为日期 (c) 根据原始列的数量向该日期添加 X 个月

let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Project Number", "Project Name", "Planned Start Date"}, "Ignore", "Savings"),
#"Added Index" = Table.AddIndexColumn(#"Unpivoted Other Columns", "Index", 0, 1, Int64.Type),
#"Mod Index" = Table.TransformColumns(#"Added Index",{{"Index", each Number.Mod(_,List.Count(Table.ColumnNames(Source))-3), Int64.Type}}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Mod Index", "Planned Start Date", Splitter.SplitTextByDelimiter("-", QuoteStyle.Csv), {"Planned Start Date.1", "Planned Start Date.2"}),
#"Added Custom1" = Table.AddColumn(#"Split Column by Delimiter", "Custom", each Date.FromText("01 "& [Planned Start Date.1] & "20"&[Planned Start Date.2])),
#"Added Custom" = Table.AddColumn(#"Added Custom1", "Date2", each  Date.AddMonths([Custom],[Index])),
#"Added Custom2" = Table.AddColumn(#"Added Custom", "Date", each Date.ToText([Date2],"MMM-yy")),
#"Removed Other Columns" = Table.SelectColumns(#"Added Custom2",{"Project Number", "Project Name", "Savings", "Date"})
 in  #"Removed Other Columns"

您需要在 Power BI 中将 Excel.CurrentWorkbook 替换为 Excel.WorkBook

【讨论】:

    【解决方案3】:

    这与 Power Query 但代码更短并且与列数无关

    let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Project Number", "Project Name", "Planned Start Date"}, "Ignore", "Savings"),
        #"Changed Type" = Table.TransformColumnTypes(#"Unpivoted Other Columns",{{"Planned Start Date", type date}}),
        #"Added Custom" = Table.AddColumn(#"Changed Type", "Date", each Date.AddMonths([Planned Start Date] ,  Number.FromText(Text.End([Ignore],1))-1),  type date),
        #"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Ignore"})
    in
        #"Removed Columns"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多