我在 Python Polars 中有这个数据框,其尺寸为 (8442x7),基本上一周中的每一天都有 1206 行。星期几显示为一个简单的字符串。
我想利用
pl.Enum
对 ISO_WEEKDAY
列进行编码,从而节省磁盘空间。请参阅以下代码。
#!/usr/bin/env python3
# encoding: utf-8
import calendar, polars as pl
weekdays:pl.Enum=pl.Enum(categories=iter(calendar.day_name))
df: pl.DataFrame = pl.read_parquet(source='some_data.parquet') # About 268K
# df has a column called ISO_WEEKDAY whose values are Monday, Tuesday...Sunday
weekdays:pl.Enum=pl.Enum(categories=iter(calendar.day_name)) # Encode all weekdays in the enum
df=df.with_columns(pl.col(ISO_WEEKDAY).cast(dtype=weekdays))
df.write_parquet('new_file.parquet') # ~ Same 268K
但似乎没有发生,即即使将列转换为
pl.Enum
pl.DataFrame.estimated_size()
方法)实际上会变大。那么,即使每个列值重复 1206 次,
pl.Enum
到底是否可取?
当 Polars(和大多数作家)编写镶木地板时,他们会同时使用压缩和字典编码,因此您不应期望使用分类或枚举在磁盘上带来太多(如果有的话)好处。
但在内存中,情况有所不同,它不会对字符串进行字典编码,因此重复的字符串实际上会占用额外的空间。
例如如果我这样做
df=pl.DataFrame({
'a':pl.date_range(pl.date(2020,1,1), pl.date(2024,12,31),'1d',eager=True)
}).with_columns(weekday=pl.col('a').dt.strftime("%A"))
那么
df.estimated_size()
是 20358,df.with_columns(pl.col('weekday').cast(pl.Enum(df['weekday'].unique()))).estimated_size()
是 14666,所以只是原始足迹的 72%。
这是一个比你的小得多的 df,所以我不知道为什么你没有看到带有枚举而不是字符串的更小的 df。