Power Query 倾斜数据

Posted

技术标签:

【中文标题】Power Query 倾斜数据【英文标题】:Power Query Skewed data 【发布时间】:2017-02-09 09:32:38 【问题描述】:

我在电源查询中遇到问题,我的数据来自拆分为页面的报告,并且某些页面将数据倾斜到不同的列。我认为可能存在基于错误的解决方案,但我希望它更加冗余,而不是依赖文本与数字纠错。主要是因为有时在某些情况下可能是字母的数据在其他情况下可能是数字。我准备了一个随机生成名称和代码替换的数据集。我还不得不稍微整理一下数据,以给出不同班次的例子,并说明从不同页面拆分的记录。

https://drive.google.com/file/d/0B2qUbAWJXgfyNlByV2RHODJzQjA/view?usp=sharing

数据集中有 12 条记录,最终每条记录包含一行。 第 1 页是从源文档中剥离的原始数据。这些是检查历史记录(已屏蔽),需要将每条记录移动到一行,并为四个特定区域提供单独的列:

[姓名、日期、支票号码等][收入][扣除][税收]

记录信息,包括姓名、日期、记录 ID 编号和金额,是从原始数据中提取和格式化的第一件事。我在 NameData 和 CheckData 中应用的步骤将展示如何提取和格式化这些记录,而且本节中的一些倾斜数据很容易与合并函数和条件列相协调。

每个单独的付款项目(收入代码、扣除代码或税代码)都经过格式化,然后转到它自己的列。您可以在收益查询中看到此操作的示例。 PayItemReference 查询是一些基本过滤器,我将其用作 My Pay Items 的起点。您可以在该查询中看到代码将在列之间移动,文本和数字混合在一起。代码及其值之间可以有空格,也可以没有空格,也可以完全移位列。

我正在努力将代码及其值合并到常规列中,然后我可以合并、取消透视、透视等以达到最终格式。我曾尝试使用条件列和错误,但在原始数据集上总是存在小问题。我只需要一些新的眼光和数据的新方法。

【问题讨论】:

您需要详细解释数据的外观以及应如何将其拆分为列。在您的示例中,我根本看不到任何变化,因为所有行都有 7 个位置。同样对于数字,如果有任何 ,.- 或货币符号,并且数据的文化也可能相关(例如,日期 01/02/2017 在英国是 2 月 1 日,在美国是 1 月 2 日),则它可能是相关的. 我希望我的编辑能让数据更形象一些。所有数字通常都是十进制数字,因为它们可以代表 $ 货币或十进制小时记录,具体取决于上下文。 这还不够。如果没有明确的说明如何确定输入的哪一部分应该放在哪一列中,以及所有可能的替代转变,我们将无法为您提供帮助。 原始数据集很难描述,我很抱歉,我也无法共享数据,因为它受 HIPAA 监管。让我看看我能做些什么来给你一个更清晰的例子,以及我打算用它做什么。 @CRSPLK 太糟糕了,你没有使用@来解决你对我的评论 - 我今天才看到。无论如何,希望我的解决方案有所帮助。不过,它可能需要一些微调。 【参考方案1】:

这是一项具有挑战性的任务。

首先,最好将表拆分为页面,因为每个页面的列结构可能是唯一的。因此,我形成表格列表,每个表格为一页。然后我必须处理每一页:提取列名,为每一行添加摘要信息,过滤不需要的行,并设置列名。这是通过使用自定义函数ConvertTable 对列表中的每个表完成的。之后,您只需合并结果表。

这里:

let
    Source = Excel.CurrentWorkbook()[Name="Table1"][Content],
    AddRowNum = Table.AddColumn(Table.AddIndexColumn(Source, "Index", 1, 1), "RowNum", each Number.Mod([Index]-1, 52)+1, type number),
    CountTables = 1..(Number.RoundUp(Table.RowCount(AddRowNum)/52, 0)),
    ListTables = List.Transform(CountTables, (ListItem)=>Table.SelectRows(AddRowNum, each [Index] > 52 * (ListItem - 1) and [Index] <= 52 * ListItem)),

    ConvertTable = (tbl as table) as table =>
    let
        hdr1 = Table.Transpose(Table.FillDown(Table.Transpose(Table.FromRecords(tbl6)), "Column1")),
        hdr2 = Table.FromRecords(tbl7),
        ColNames = Table.Transpose(Table.SelectColumns(Table.FirstN(Table.AddColumn(Table.Transpose(Table.Combine(hdr1, hdr2)), "ColumnName", each [Column1] & ": " & [Column2]), 19), "ColumnName")),
        AddPayDate = Table.AddColumn(tbl, "Pay Date", each if [RowNum] > 8 and Text.Trim(tbl[RowNum]-2[Column9]) = "Pay Date" then [Column9] else null, type date),
        AddPeriodEndDate = Table.AddColumn(AddPayDate, "Period End Date", each if [RowNum] > 8 and Text.Trim(tbl[RowNum]-2[Column12]) = "Period End Date" then [Column12] else null, type date),
        AddJobCode = Table.AddColumn(AddPeriodEndDate, "Job Code", each if [RowNum] > 8 and Text.Trim(tbl[RowNum]-2[Column14]) = "Job Code" then [Column14] else null, Int64.Type),
        AddCheckInfo = Table.AddColumn(AddJobCode, "Check Info", each if [RowNum] > 8 and Text.Trim([Column1]) = "Check Printed:" then Table.Transpose(Table.SelectRows(Table.Transpose(Table.FromRecords(_)), each [Column1] <> null)) else null),
        ExpandedCheckInfo = Table.ExpandTableColumn(AddCheckInfo, "Check Info", "Column4", "Column6", "Column8", "Check Amount", "Direct Deposit", "Net"),
        FillUp = Table.FillUp(ExpandedCheckInfo, "Column3", "Check Amount", "Direct Deposit", "Net")//Table.AddColumn(AddJobCode, "tmp2", each if [RowNum] < 9 then "" else (if Text.Trim([Column1]) = "Check Printed:" then (if [Column3] = null then -1 else [Column3]) else null), type text), "tmp2"),
        FillDown = Table.FillDown(FillUp, "Column1", "Column5", "Pay Date", "Period End Date", "Job Code"),
        AddCheckEEIDfixed = Table.AddColumn(FillDown, "Check:EEID.fixed", each Text.From([Column5]) & ":" & Text.From([Column3]), type text),
        FilteredExtraRows = Table.SelectRows(AddCheckEEIDfixed, each [RowNum] > 8 and Text.Trim([Column1]) <> "Check Printed:" and Text.Trim([Column7]) <> "PerControl" and Text.Trim(tbl[RowNum]-2[Column7]) <> "PerControl" and [#"Check:EEID.fixed"] <> null),
        DemotedHeaders = Table.DemoteHeaders(FilteredExtraRows),
        GetColumnNames1 = Table.Combine(Table.FromRecords(DemotedHeaders0), ColNames),
        GetColumnNames2 = Table.PromoteHeaders(Table.FillDown(GetColumnNames1, Table.ColumnNames(GetColumnNames1))),
        SetColumnNames = Table.PromoteHeaders(Table.Combine(GetColumnNames2, FilteredExtraRows))
    in
        SetColumnNames,

    ConvertedList = List.Transform(ListTables, (t) => ConvertTable(t)),
    GetWholeTable = Table.Combine(ConvertedList)
in
    GetWholeTable

【讨论】:

以上是关于Power Query 倾斜数据的主要内容,如果未能解决你的问题,请参考以下文章

hive数据倾斜及处理

Spark数据倾斜解决方案

hive数据倾斜及解决方案

3万字细品数据倾斜

如何处理hive中的数据倾斜

HIVE优化场景七--数据倾斜--group by 倾斜