Скользящие расчеты KPI в полярах, индекс не отображается

Как добавить скользящие ключевые показатели эффективности в исходный фрейм данных в полярах? когда я группирую, я не вижу индекса и поэтому не могу присоединиться? Я хочу сохранить все исходные столбцы в фрейме данных нетронутыми, но добавить в фрейм данных скользящий KPI?

Код Панды:

groups_df = df[mask_for_filter].groupby(['group_identifier'])
rolling_kpi = groups_df[['col_1', 'col_2']].rolling(15, min_periods=1, center=True).median().reset_index(level='group_identifier').sort_index()

df.loc[mask_for_filter, 'col_1_median'] = rolling_kpi['col_1']
df.loc[mask_for_filter, 'col_2_median'] = rolling_kpi['col_2']

Поляры:

df = df.filter(mask_for_filter).group_by('group_identifier').agg(
    col_1_median=pl.col('col_1').rolling_median(15, min_periods=1, center=True),
    col_2_median=pl.col('col_2').rolling_median(15, min_periods=1, center=True))

Код: result_df должен быть таким же, как df, за исключением того, что с дополнительными скользящими медианными столбцами, чего не происходит выше... плюс нет индекса, поэтому невозможно объединить/объединить

import polars as pl
import numpy as np

np.random.seed(0)
data = {
    'group_identifier': np.random.choice(['A', 'B', 'C'], 100),
    'col_1': np.random.randn(100).round(2),
    'col_2': np.random.randn(100).round(2),
    'other_col': np.random.randn(100).round(2)
}

df = pl.DataFrame(data)

mask_for_filter = df['col_1'] > 0

result_df = df.filter(mask_for_filter).group_by('group_identifier').agg(
    col_1_median=pl.col('col_1').rolling_median(15, min_periods=1, center=True),
    col_2_median=pl.col('col_2').rolling_median(15, min_periods=1, center=True)
)

Добавьте к вопросу примеры данных и ожидаемый результат. См. stackoverflow.com/help/minimal-reproducible-example.

Dogbert 30.07.2024 14:43
mask_for_avg нигде не определяется.
Dogbert 30.07.2024 15:17

Хотите ли вы, чтобы в результате были те же строки, что и df или result_df. В первом случае: какую скользящую медиану следует назначить строкам в df с pl.col(col_1) <= 0.

Hericks 30.07.2024 15:39
Почему в 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
3
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Похоже, вам не нужно группировать, а вместо этого запустить rolling_median() над окном.

  • over(), чтобы ограничить вычисления в пределах group_identifier.
  • name.suffix() для присвоения имен новым столбцам.

Если вам нужны только отфильтрованные строки:

(
    df
    .filter(mask_for_filter)
    .with_columns(
        pl.col("col_1", "col_2")
        .rolling_median(15, min_periods=1, center=True)
        .over("group_identifier")
        .name.suffix("_median")
    )
)

┌──────────────────┬───────┬───────┬───────────┬──────────────┬──────────────┐
│ group_identifier ┆ col_1 ┆ col_2 ┆ other_col ┆ col_1_median ┆ col_2_median │
│ ---              ┆ ---   ┆ ---   ┆ ---       ┆ ---          ┆ ---          │
│ str              ┆ f64   ┆ f64   ┆ f64       ┆ f64          ┆ f64          │
╞══════════════════╪═══════╪═══════╪═══════════╪══════════════╪══════════════╡
│ B                ┆ 0.01  ┆ 1.68  ┆ 1.12      ┆ 0.83         ┆ -0.46        │
│ B                ┆ 0.37  ┆ -0.26 ┆ 0.04      ┆ 0.85         ┆ -0.66        │
│ A                ┆ 0.72  ┆ -0.38 ┆ 0.47      ┆ 0.93         ┆ -0.44        │
│ A                ┆ 0.36  ┆ -0.51 ┆ -0.4      ┆ 0.86         ┆ -0.5         │
...
└──────────────────┴───────┴───────┴───────────┴──────────────┴──────────────┘

Или, если вам это нужно в исходном DataFrame

  • When/then() дважды — верхний, чтобы назначить скользящую медиану только тем строкам, которые имеют col_1 > 0, и второй, чтобы не включать строки, которые будут фильтроваться при вычислении скользящей медианы.
(
    df
    .with_columns(
        pl.when(pl.col("col_1") > 0).then(
            pl.when(pl.col("col_1") > 0).then(pl.col("col_1", "col_2"))
            .rolling_median(15, min_periods=1, center=True)
            .over("group_identifier")
        )
        .name.suffix("_median")
    )
)

Если вы хотите добавить больше агрегатов, вы можете обобщить их (хотя я не уверен, что они достаточно читаемы, чтобы перейти к производству):

(
    df
    .with_columns(
        pl.when(pl.col("col_1") > 0).then(
            transform(
                pl.when(pl.col("col_1") > 0).then(pl.col("col_1", "col_2")),
                15, min_periods=1, center=True
            )
            .over("group_identifier")
        )
        .name.suffix(suffix)
        for transform, suffix in [
            (pl.Expr.rolling_median, "_median"),
            (pl.Expr.rolling_mean, "_mean"),
        ]
    )
)

Очень круто, я думаю, что последующие действия не подходят, но спрошу, хочу ли я использовать скользящее среднее, а также скользящую медиану, имеет ли смысл повторять приведенный выше блок со средним значением или есть более чистый способ сделать это над самим собой?

r ram 30.07.2024 15:59

Я добавил возможность к ответу

Roman Pekar 30.07.2024 16:15

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