python-3.x 将列表项的polars列水平分解为新列

x8goxv8g  于 10个月前  发布在  Python
关注(0)|答案(2)|浏览(149)

有没有一种polars原生的方式来水平地展开一列列表?
例如,从这个开始:

df = pl.DataFrame(
    {
        "letters": ["a", "a", "b", "c"],
        "numbers": [[1, 1], [2, 3], [4, 5], [6, 7]],
    }
)

字符串
对这个?

df = pl.DataFrame(
    {
        "letters": ["a", "a", "b", "c"],
        "numbers_a": [1, 2, 4, 6],
        "numbers_b": [1, 3, 5, 7]
    }
)


我知道.explode()的方法,但afaik这是唯一可能使用垂直

rhfm7lfc

rhfm7lfc1#

有两种方法可以做到这一点。

struct/unnest

最简单的是.list.to_struct,然后unnest

from string import ascii_lowercase

(
    df
    .with_columns(
        pl.col('numbers').list.to_struct(
            fields=lambda idx: f"numbers_{ascii_lowercase[idx]}",
            n_field_strategy='max_width'
            )
        )
    .unnest('numbers')
)

字符串

获取

from string import ascii_lowercase
max_width=df['numbers'].list.len().max()
(
    df
    .select(
        pl.exclude('numbers'), 
        *[pl.col('numbers').list.get(x).alias(f"numbers_{ascii_lowercase[x]}") 
          for x in range(max_width)]
        )
    )


在任何一种情况下,你都会得到:

shape: (4, 3)
┌─────────┬───────────┬───────────┐
│ letters ┆ numbers_a ┆ numbers_b │
│ ---     ┆ ---       ┆ ---       │
│ str     ┆ i64       ┆ i64       │
╞═════════╪═══════════╪═══════════╡
│ a       ┆ 1         ┆ 1         │
│ a       ┆ 2         ┆ 3         │
│ b       ┆ 4         ┆ 5         │
│ c       ┆ 6         ┆ 7         │
└─────────┴───────────┴───────────┘


在前一种情况下,你可以更容易地链接方法,但第二种情况依赖于首先确定max_width,这是不太灵活的。第二种方法 * 可能 * 性能更好,但我真的不知道,所以值得检查。

nbysray5

nbysray52#

对于那些像我一样不能使用.list()方法的人,

# get timestamps as list
numbers_col= list(df['numbers'])

# transpose this
numbers_col = list(map(list, zip(*numbers_col)))

# add the columns back in
df = df.with_columns(
    pl.Series(name='numbers_a', values=numbers_col[0]),
    pl.Series(name='numbers_b', values=numbers_col[1]),
)

字符串
我的问题是有没有波兰人的方式,所以我会接受另一个答案。

相关问题