Совокупный расчет по строкам?

Предположим, у меня есть функция:

def f(prev, curr):
  return prev * 2 + curr

(просто пример, могло быть что угодно)

И фрейм данных Polars:

| some_col | other_col |
|----------|-----------|
|    7     |    ...
|    3     |
|    9     |
|    2     |

Я хотел бы использовать f в своем фрейме данных в совокупности, и результат будет следующим:

| some_col | other_col |
|----------|-----------|
|    7     |    ...
|    17    |
|    43    |
|    88    |

Я понимаю, что, естественно, такой тип вычислений не будет очень эффективным, поскольку его придется выполнять по одной строке за раз (по крайней мере, в общем случае).

Очевидно, я могу перебирать строки. Но есть ли элегантный идиоматический способ сделать это в Polars?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
0
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это зависит от того, какую именно операцию вам необходимо выполнить.

Приведенный вами пример можно выразить через .cum_sum() с дополнительной арифметикой:

def plus_prev_times_2(col):
    x = 2 ** pl.int_range(pl.len() - 1).reverse()
    y = 2 ** pl.int_range(1, pl.len())
    cs = (x * col.slice(1)).cum_sum()
    return cs / x + col.first() * y

df = pl.DataFrame({"some_col": [7, 3, 9, 2]})

df.with_columns(
   pl.col.some_col.first()
     .append(pl.col.some_col.pipe(plus_prev_times_2))
     .alias("plus_prev_times_2")
)     
shape: (4, 2)
┌──────────┬───────────────────┐
│ some_col ┆ plus_prev_times_2 │
│ ---      ┆ ---               │
│ i64      ┆ f64               │
╞══════════╪═══════════════════╡
│ 7        ┆ 7.0               │
│ 3        ┆ 17.0              │
│ 9        ┆ 43.0              │
│ 2        ┆ 88.0              │
└──────────┴───────────────────┘

Вертикальная складка/сканирование

В общем, я считаю, что то, о чем вы просите, называется «Вертикальное сгибание/сканирование».

Polars предлагает только горизонтальную версию, pl.cum_fold

df = pl.DataFrame(dict(a=[7], b=[3], c=[9], d=[2]))

df.with_columns(
   pl.cum_fold(acc=0, function=lambda acc, x: acc * 2 + x, exprs=pl.all())
)
shape: (1, 5)
┌─────┬─────┬─────┬─────┬──────────────┐
│ a   ┆ b   ┆ c   ┆ d   ┆ cum_fold     │
│ --- ┆ --- ┆ --- ┆ --- ┆ ---          │
│ i64 ┆ i64 ┆ i64 ┆ i64 ┆ struct[4]    │
╞═════╪═════╪═════╪═════╪══════════════╡
│ 7   ┆ 3   ┆ 9   ┆ 2   ┆ {7,17,43,88} │
└─────┴─────┴─────┴─────┴──────────────┘

Как обсуждалось в выпуске, вертикальный эквивалент был бы крайне неэффективен.

Для более эффективного подхода вы можете писать плагины на Rust:

Но использовать что-то вроде numba, вероятно, проще реализовать.

Существует несколько существующих ответов numba, например.

Спасибо! В общем случае (вертикальное сканирование) кажется, что это действительно не поддерживается изначально.

ldmat 13.07.2024 19:26

Другие вопросы по теме