假设我有一个名为“结构”的列,它是每个结构中包含“a”和“b”的结构列表。我想避免使用爆炸,例如我的数据结构非常复杂(而且很大),我想尽可能地单独使用列表。
# Create a list of lists of structures
list_of_structs = [
[{"a":1, "b": 2}, {"a":3, "b": 4}, {"a":5, "b": 4}]
]
# Create a DataFrame from the list of lists
df = pl.DataFrame({"structures": list_of_structs})
我的预期结果将是按 B 分组的列表列表
[[(a1, b2)], [[(a3,b4)], (a5, b4)]]
我想执行某种“按 B 对所有元素进行分组”(然后使用 concat_list 进行聚合),在 Spark 中代码(参见我如何引用 X 和 Y)如下所示:
arrays_grouped = F.array_distinct(
F.transform(
F.col("structures"),
lambda x: (
F.filter(F.col("structures"),
lambda y: x.field("b") == y.field("b")
)
),
)
)
但是在极地中我只能看到 eval 运算符。 https://docs.pola.rs/py-polars/html/reference/expressions/api/polars.Expr.list.eval.html#polars.Expr.list.eval。 但是,我无法从 eval 外部引用除 pl.element() 之外的任何内容,所以我陷入了困境。
我是否需要在插件中实现此功能,或者是否可以使用提供的 API 来实现?这是我现有的方法,不起作用(可能受到影响,因为我已经使用 Spark 函数很长时间了)。
df = df.with_columns(
#Gets all unique "b"
pl.col("structures").list.eval(
pl.element().struct.field("b")
#Tries to filter structures all unique "b"
).list.unique().list.eval(
pl.struct(
base:= pl.element(),
df.get_column("structures").list.eval(
#Idk what this base value is, but its not filtering, if I replace it by hardcoded-4 it does filter 4s correctly
pl.element().filter(pl.element().struct.field("b") == base)
)
)
)
)
我认为收集可能是可行的,但我什至很难开始使用它,因为我找不到要收集的索引(与 eval 类似的问题)
好吧,在考虑回答@Roman Pekar之后,我成功了,这就是它的样子
df = df.select(
df.get_column("structures").list.explode().struct.unnest().group_by("b").agg(
pl.struct(pl.col("a"),pl.col("b"))
).to_struct("structures")
)
我的错误是我试图在“expr”级别工作(因此不需要数据帧,可以说我们的 Spark 库仅返回表达式),这与我们现在使用 Spark 所做的类似。
我想在该库的极地版本中,我们必须返回一个直接转换数据帧的 lambda(这样我们就可以访问 df.get_column...)。有没有办法在没有“get_column”的情况下执行相同的操作?我期望 pl.col 是一个相当于 get_column 的后期绑定:(