df_1 = pl.DataFrame({
'name': ['Alpha', 'Alpha', 'Alpha', 'Alpha', 'Alpha'],
'index': [0, 3, 4, 7, 9],
'limit': [12, 18, 11, 5, 9],
'price': [10, 15, 12, 8, 11]
})
┌───────┬───────┬───────┬───────┐
│ name ┆ index ┆ limit ┆ price │
│ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 ┆ i64 │
╞═══════╪═══════╪═══════╪═══════╡
│ Alpha ┆ 0 ┆ 12 ┆ 10 │
│ Alpha ┆ 3 ┆ 18 ┆ 15 │
│ Alpha ┆ 4 ┆ 11 ┆ 12 │
│ Alpha ┆ 7 ┆ 5 ┆ 8 │
│ Alpha ┆ 9 ┆ 9 ┆ 11 │
└───────┴───────┴───────┴───────┘
Мне нужно добавить новый столбец, чтобы сообщить мне, при каком индексе (большем текущего) цена равна или превышает текущий предел.
В приведенном выше примере ожидаемый результат:
┌───────┬───────┬───────┬───────┬───────────┐
│ name ┆ index ┆ limit ┆ price ┆ min_index │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 ┆ i64 ┆ i64 │
╞═══════╪═══════╪═══════╪═══════╪═══════════╡
│ Alpha ┆ 0 ┆ 12 ┆ 10 ┆ 3 │
│ Alpha ┆ 3 ┆ 18 ┆ 15 ┆ null │
│ Alpha ┆ 4 ┆ 11 ┆ 12 ┆ 9 │
│ Alpha ┆ 7 ┆ 5 ┆ 8 ┆ 9 │
│ Alpha ┆ 9 ┆ 9 ┆ 11 ┆ null │
└───────┴───────┴───────┴───────┴───────────┘
Пояснение результатов столбца «min_index»:
- 1-я строка, где предел равен 12: из 2-й строки и далее минимальный индекс, цена которого равна или превышает 12, равен 3.
- 2-я строка, где предел равен 18: начиная с 3-й строки, нет индекса, цена которого равна или больше, чем 18.
- 3-я строка, где предел равен 11: начиная с 4-й строки, минимальный индекс, цена которого равна или превышает 11, равен 9.
- 4-я строка, где предел равен 5: начиная с 5-й строки, минимальный индекс, цена которого равна или превышает 5, равен 9.
- 5-я строка, где предел равен 9: поскольку это последний строки, нет другого индекса, цена которого равна или превышает 9.
# Import Polars.
import polars as pl
# Create a sample DataFrame.
df_1 = pl.DataFrame({
'name': ['Alpha', 'Alpha', 'Alpha', 'Alpha', 'Alpha'],
'index': [0, 3, 4, 7, 9],
'limit': [12, 18, 11, 5, 9],
'price': [10, 15, 12, 8, 11]
})
# Group by name, so that we can vertically stack all row's values into a single list.
df_2 = df_1.group_by('name').agg(pl.all())
# Put the lists with the original DataFrame.
df_3 = df_1.join(
other=df_2,
on='name',
suffix='_list'
)
# Explode the dataframe to long format by exploding the given columns.
df_3 = df_3.explode([
'index_list',
'limit_list',
'price_list',
])
# Filter the DataFrame for the condition we want.
df_3 = df_3.filter(
(pl.col('index_list') > pl.col('index')) &
(pl.col('price_list') >= pl.col('limit'))
)
# Get the minimum index over the index column.
df_3 = df_3.with_columns(
pl.col('index_list').min().over('index').alias('min_index')
)
# Select only the relevant columns and drop duplicates.
df_3 = df_3.select(
pl.col(['index', 'min_index'])
).unique()
# Finally join the result.
df_final = df_1.join(
other=df_3,
on='index',
how='left'
)
print(df_final)
Подробнее здесь: https://stackoverflow.com/questions/793 ... -in-column