Power Query:在列中出现值后删除下 n 行

Posted

技术标签:

【中文标题】Power Query:在列中出现值后删除下 n 行【英文标题】:Powerquery: Remove next n rows after occurence of value in column 【发布时间】:2021-12-29 11:20:30 【问题描述】:

我经常在 powerquery 中有大型数据集,我需要删除/过滤出同一行,以及以下 13 个每当某个值出现时,在这种情况下是“页面”。这在整个专栏中多次出现。

我尝试通过添加索引列和 [Index]+1 恶作剧来引用下一行/上一行,但这要么不起作用,要么加载时间超过 15 分钟。

我尝试使用 Table.RemoveFirstN(Text.Contains([Column], "Page"), 13) 设置一些东西,但只是出错了。

有谁知道我如何过滤出现值的行,以及 Powerquery 中的下 n 行(索引?)?

亲切的问候,

【问题讨论】:

【参考方案1】:

这似乎工作正常

我们添加一个索引。测试“页面”。在新列中,如果存在 Page,则复制索引。填写然后分组。将第二个索引添加到分组中。展开所有列。过滤掉第二个索引

let Source = Excel.CurrentWorkbook()[Name="Table1"][Content],
#"Changed Type" = Table.TransformColumnTypes(Source,"Merged Price Country", type text),
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1),
#"Added Custom" = Table.AddColumn(#"Added Index", "Custom", each try if Text.Contains([Merged Price Country],"Page") then [Index] else null otherwise null),
#"Filled Down" = Table.FillDown(#"Added Custom","Custom"),
mGroup = Table.Group(#"Filled Down", "Custom", "Data", each Table.AddIndexColumn(_, "Index2", 1, 1), type table),
#"Removed Columns" = Table.RemoveColumns(mGroup,"Custom"),
// expand all columns
List = List.Union(List.Transform(#"Removed Columns"[Data], each Table.ColumnNames(_))),
#"Expanded Data" = Table.ExpandTableColumn(#"Removed Columns", "Data", List,List),
#"Filtered Rows" = Table.SelectRows(#"Expanded Data", each [Custom]=null or [Index2] > 14),
#"Removed Columns1" = Table.RemoveColumns(#"Filtered Rows","Index", "Custom", "Index2")
in #"Removed Columns1"

我跳过了在上面代码中的分组上使用 Table.RemoveFirstN() 的情况下,你想保留前导行,但你可以使用它而不是添加第二个索引并像下面这样过滤

let Source = Excel.CurrentWorkbook()[Name="Table3"][Content],
#"Changed Type" = Table.TransformColumnTypes(Source,"Merged Price Country", type text),
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1),
#"Added Custom" = Table.AddColumn(#"Added Index", "Custom", each try if Text.Contains([Merged Price Country],"Page") then [Index] else null otherwise null),
#"Filled Down" = Table.FillDown(#"Added Custom","Custom"),
mGroup = Table.Group(#"Filled Down", "Custom", "Data", each Table.RemoveFirstN(_, 13), type table),
#"Removed Columns" = Table.RemoveColumns(mGroup,"Custom"),
// expand all columns
List = List.Union(List.Transform(#"Removed Columns"[Data], each Table.ColumnNames(_))),
#"Expanded Data" = Table.ExpandTableColumn(#"Removed Columns", "Data", List,List),
#"Removed Columns1" = Table.RemoveColumns(#"Expanded Data","Index", "Custom")
in #"Removed Columns1"

【讨论】:

非常感谢,这在我的查询中非常有用。出于某种原因,Ron 的方法落后于我的查询,所以我目前正在使用你的方法。你帮我省了很多麻烦,因为我真的为此头疼:)。 太棒了。如果可行,请通过切换箭头附近的复选标记来接受答案【参考方案2】:

不同的方法。想知道哪个可能更快:

创建要删除的行列表(按行号) 选择不在该列表中的行
let
    Source = Excel.CurrentWorkbook()[Name="Table12"][Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,"Text", type text, "Data", Int64.Type),

//Add index column
    #"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1, Int64.Type),

//create list rows to be removed
    textCol = List.Transform(#"Added Index"[Text], each 
        if _ = null then null 
        else if Text.Contains(_,"Page",Comparer.OrdinalIgnoreCase) then "RemoveMe" 
        else _),

//create list of positions to be removed
    removePos = List.Combine(List.Transform(List.PositionOf(textCol,"RemoveMe",Occurrence.All), each _..List.Min(_+13, List.Count(textCol)))),

//Filter the table using the "RemoveMe" list
    filter = Table.SelectRows(#"Added Index", each not List.Contains(removePos,[Index])),
    #"Removed Columns" = Table.RemoveColumns(filter,"Index")
    
in
    #"Removed Columns"

【讨论】:

嗨,罗恩,首先非常感谢。看起来,这确实应该完美运行,但由于某种原因,它只是落后于我的整个查询,所以我选择了@horseyride 的解决方案。不管怎样,谢谢,这是一个有创意的解决方案,应该可以更快地工作,我想说... @tgsAvylaar “落后”我假设你的意思是跑得很慢。如果是这样的话,我想知道减速在哪里,是否可以改进。你能给我信息来重现你的数据样本吗?

以上是关于Power Query:在列中出现值后删除下 n 行的主要内容,如果未能解决你的问题,请参考以下文章

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

Power Query - 替换新列中的文本

Power Query / Power BI - 用另一列中的值替换空值

Power Query - 在组函数中计算列中的非空白

powerquery的sum公式

SQL Server 在列中搜索文本