Power Query 根据另一列转换一列

Posted

技术标签:

【中文标题】Power Query 根据另一列转换一列【英文标题】:Power Query Transform a Column based on Another Column 【发布时间】:2015-07-21 19:39:20 【问题描述】:

我一直认为这应该很容易,但答案却在逃避我。在 Excel Power Query 中,我想根据另一列的值转换列的每一行中的值。例如,假设我有 Table1 如下:

Column A | Column B
-------------------
X        | 1
Y        | 2

我想根据 B 列中的值转换 A 列中的值,而不必添加新列并替换原始 A 列。我尝试使用 TransformColumns 但输入只能是目标列的值- 我无法从 TransformColumns 函数中访问行/记录中的其他字段值。我希望希望能够做这样的事情:

=Table.TransformColumns(Table1, "Column A", each if [Column B]=1 then "Z" else _ )

这会导致:

Column A | Column B
-------------------
Z        | 1
Y        | 2

我知道有办法做到这一点,但我正试图找到一种步骤/转换最少的方法。例如,我知道我可以使用 Table.AddColumn 根据查看 B 列的函数添加 new A 列,但随后我必须删除原始 A 列并将其替换为新的需要多个额外步骤的 A 列。

【问题讨论】:

【参考方案1】:

这就是我最终这样做的方式:

Table1:
Column A | Column B
-------------------
X        | 1
Y        | 2

= Table.FromRecords(Table.TransformRows(Table1,
    (r) => Record.TransformFields(r,
        "A", each if r[Column B]="1" then "Z" else _)))

结果:

Column A | Column B
-------------------
Z        | 1
Y        | 2

这样,您可以使用 Record.TransformFields 函数中的嵌套列表一次转换多个列。

【讨论】:

【参考方案2】:

另一种选择是:

= Table.ReplaceValue(Table1, each [Column A], each if [Column B]=1 then "Z" else [Column A] , Replacer.ReplaceText, "Column A")

代码更具可读性,但一次只能应用于一列。

大部分都可以使用 UI 生成,如下所示:http://www.thebiccountant.com/2017/07/23/transforming-a-column-with-values-from-another-column-in-powerbi-and-powerquery-in-excel/

【讨论】:

【参考方案3】:

向 LoganTheSnowEater 致敬……我喜欢你的回答。您提到它可以扩展为多个操作,我想发布一个我如何成功使用它的示例:

#"Patch Records" = Table.FromRecords(Table.TransformRows(#"Sorted Rows",
(r) => Record.TransformFields( r, 
    "Min Commit", each 
        if r[service_id] = "21430" then 81 else
        if r[service_id] = "24000" then 230 else
        if r[service_id] = "24008" then 18 else
        if r[service_id] = "24009" then 46.9 else
        _,
    "Installed", each 
        if r[service_id] = "21430" then 90 else
        if r[service_id] = "24000" then 230 else
        if r[service_id] = "24008" then 18 else
        if r[service_id] = "24009" then 52 else
        _,
    "Requested", each 
        if r[service_id] = "21430" then 90 else
        if r[service_id] = "24000" then 230 else
        if r[service_id] = "24008" then 18 else
        if r[service_id] = "24009" then 52 else
        _)))

我唯一感到惊讶的是,我必须在完成后重置所有数据类型,但回想起来这很有意义。

附言我没有足够的声望点来将此作为解决方案的评论发布

【讨论】:

【参考方案4】:

以 LoganTheSnowEater 的回答为基础,这是一种使用 Table.FromRecords 中的第二个参数保留表列类型的方法,如M Reference 中所指定:

Table1:
Column A | Column B
-------------------
    X    |    1
    Y    |    2

编辑:更新为使用更好的方法从使用 Value.Type 的表中提取表类型 - 此外,为了完整性,一次修改多个列。感谢 Value.Type 这个伟大的 convo:https://social.technet.microsoft.com/Forums/en-US/636e9b44-6820-4ff2-ab60-5dd6a5307bd2/type-conversion-mysteries

=Table.FromRecords(
    Table.TransformRows(
        Table1,
        (r) => 
        Record.TransformFields(
            r,
            
                "Column A", each if r[Column B]="1" then "Z" else _,
                "Column B", each if r[Column A]="Y" then "99" else _
            
        )
    ),
    Value.Type(Table1)
)

【讨论】:

【参考方案5】:

抱歉,我编辑公式不太好,现在可以使用:

= Table.ReplaceValue(   #"Removed Columns", 
                   each [Contract Start Date],
                    each if [Contract Start Date] < #date(2019,01,01) then #date(2019,01,01) else
                          [Contract Start Date]
                    ,Replacer.ReplaceValue,
                    "Contract Start Date")

【讨论】:

【参考方案6】:

您不能使用这样的步骤来转换现有列。使用新列,进行转换,然后删除现有列。有什么大不了的?在 Excel 中,您也不希望公式更改不同列的值。在 Power Query 中,公式的结果也存储在列中,而不能是提供公式输入值之一的列。

【讨论】:

这笔交易主要是我必须用几个不同的表来做这件事,感觉就像一个步骤可以一步完成而不是几个(即创建新列,删除旧列,重命名)新列)。此外,我必须对每个表的多个列执行此操作,TransformColumns 的优点在于它可以一次应用于多个列,而 AddColumn 一次添加一个。我有一个潜在的解决方案,我将表格转换为记录列表并使用 Record.TransformFields,我可以稍后共享。 不过,转换结果需要一个新列。

以上是关于Power Query 根据另一列转换一列的主要内容,如果未能解决你的问题,请参考以下文章

Power Query:当特定值出现在另一列中时如何将一个添加到列中

Table.SplitColumn拆分…Split…(Power Query 之 M 语言)

Power Query中如何把多列数据合并?

如何根据另一列值将一列分成多个?

根据另一列唯一值填充另一列

根据另一列的顺序制作一列