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:当特定值出现在另一列中时如何将一个添加到列中