如何在Polars中实现与Power Query一致的Unpivot效果?
如何在Polars中实现与Power Query一致的Unpivot效果?
我明白你遇到的问题啦——Power Query里的Table.UnpivotOtherColumns会自动跳过那些值为空的条目,但Polars默认的unpivot()不仅没明确指定要保留的列,还会把所有行(包括空值)都保留下来,导致结果和你预期的不一样。别担心,咱们通过两步简单的调整,就能实现和Power Query完全一致的效果!
核心差异说明
Power Query的Table.UnpivotOtherColumns默认做了两件事:
- 保留你指定的列(这里是
Hall和Date)作为分组依据,将其他列(Guest1-Guest4)逆透视成Attribute和Value列 - 自动过滤掉
Value为空的行
而Polars默认的unpivot():
- 会自动推断哪些列要作为索引(可能不符合你的预期)
- 默认保留所有行,包括
Value为空的条目
实现一致效果的代码
咱们只需要明确指定索引列,并开启空值忽略,就能完美对齐Power Query的行为:
import polars as pl import datetime dc = {'Hall': ['Hall1', 'Hall1', 'Hall2', 'Hall2'], 'Date': [datetime.date(2023, 2, 1), datetime.date(2023, 2, 2), datetime.date(2023, 2, 1), datetime.date(2023, 2, 4)], 'Guest1': ['A', 'X', 'R', 'S'], 'Guest2': ['B', 'Y', None, 'P'], 'Guest3': [None, 'Z', None, None], 'Guest4': [None, 'Q', None, None]} # 与Power Query Table.UnpivotOtherColumns完全对齐的写法 df = pl.from_dict(dc).unpivot( index=['Hall', 'Date'], # 指定要保留的分组列,对应Power Query的固定列 variable_name='Attribute', # 自定义逆透视后的列名,和Power Query一致 value_name='Value', # 自定义值列名,和Power Query一致 ignore_nulls=True # 自动跳过空值,对齐Power Query的行为 ) print(df)
兼容旧版Polars的写法
如果你的Polars版本低于0.19.0(ignore_nulls参数是0.19.0才新增的),可以在逆透视后手动过滤空值,效果完全一样:
# 兼容旧版Polars的写法 df = ( pl.from_dict(dc) .unpivot(index=['Hall', 'Date'], variable_name='Attribute', value_name='Value') .filter(pl.col('Value').is_not_null()) # 手动过滤空值 )
关于你想的“逐行处理”
你之前考虑的“逐行逆透视再合并”的方法完全没必要,效率会非常低(尤其是数据量大的时候)。Polars的unpivot是矢量化操作,配合内置参数或者过滤步骤,性能比逐行处理高几个量级,完全不用走那个弯路~
备注:内容来源于stack exchange,提问作者Artur
相关产品推荐
相关产品推荐

