pythonpython-polars

Polars equivalent of numpy.tile


df = pl. DataFrame({"col1": [1, 2, 3], "col2": [4, 5, 6]})

print(df)

shape: (3, 2)
┌──────┬──────┐
│ col1 ┆ col2 │
│ ---  ┆ ---  │
│ i64  ┆ i64  │
╞══════╪══════╡
│ 1    ┆ 4    │
│ 2    ┆ 5    │
│ 3    ┆ 6    │
└──────┴──────┘

I am looking for the polars equivalent of numpy.tile.
Something along the line such as df.tile(2) or df.select(pl.all().tile(2)).

The expected result should look like this:

shape: (6, 2)
┌──────┬──────┐
│ col1 ┆ col2 │
│ ---  ┆ ---  │
│ i64  ┆ i64  │
╞══════╪══════╡
│ 1    ┆ 4    │
│ 2    ┆ 5    │
│ 3    ┆ 6    │
│ 1    ┆ 4    │
│ 2    ┆ 5    │
│ 3    ┆ 6    │
└──────┴──────┘

Solution

  • You could concat several times the same DataFrame:

    out = pl.concat([df]*2)
    
    # for contiguous memory
    out = pl.concat([df]*2, rechunk=True)
    

    Or, for just 2 repeats vstack:

    out = df.vstack(df)
    

    Alternatively, using Expr.repeat_by + explode:

    N = 2
    
    (df.with_columns(pl.all().repeat_by(pl.lit(N)), pl.int_ranges(pl.lit(N)))
       .explode(pl.all())
       .sort(by='literal', maintain_order=True).drop('literal')
    )
    

    Output:

    ┌──────┬──────┐
    │ col1 ┆ col2 │
    │ ---  ┆ ---  │
    │ i64  ┆ i64  │
    ╞══════╪══════╡
    │ 1    ┆ 4    │
    │ 2    ┆ 5    │
    │ 3    ┆ 6    │
    │ 1    ┆ 4    │
    │ 2    ┆ 5    │
    │ 3    ┆ 6    │
    └──────┴──────┘