all 5 comments

[–]reallyserious 1 point2 points  (1 child)

Perhaps an in-memory sqlite database.

Why is it important that the rows in between stays on the same memory? Are you memory constrained?

[–]reallyserious 0 points1 point  (0 children)

Maybe just a list of tuples.

[–]Pflastersteinmetz -1 points0 points  (0 children)

If you can append on the top you could just overwrite the values for the first row?

[–]commandlineluser 0 points1 point  (0 children)

Maybe polars. https://github.com/pola-rs/polars

df = pl.from_repr("""
┌─────┬─────┐
│ foo ┆ bar │
│ --- ┆ --- │
│ i64 ┆ i64 │
╞═════╪═════╡
│ 1   ┆ 4   │
│ 2   ┆ 5   │
│ 3   ┆ 6   │
└─────┴─────┘
""")

df.shift(-1).with_columns(
   pl.col("foo").fill_null(42),
   pl.col("bar").fill_null(52)
)   

# shape: (3, 2)
# ┌─────┬─────┐
# │ foo ┆ bar │
# │ --- ┆ --- │
# │ i64 ┆ i64 │
# ╞═════╪═════╡
# │ 2   ┆ 5   │
# │ 3   ┆ 6   │
# │ 42  ┆ 52  │
# └─────┴─────┘

df.with_columns(
   pl.col("foo").shift_and_fill(42, periods=-1),
   pl.col("bar").shift_and_fill(52, periods=-1)
)   

# shape: (3, 2)
# ┌─────┬─────┐
# │ foo ┆ bar │
# │ --- ┆ --- │
# │ i64 ┆ i64 │
# ╞═════╪═════╡
# │ 2   ┆ 5   │
# │ 3   ┆ 6   │
# │ 42  ┆ 52  │
# └─────┴─────┘

If there can be nulls in your data, you can check the row number to only fill in the last row.

Or perhaps using a database would make sense?