У меня есть большой набор данных, и мне нужно выполнить несколько последовательных медленных объединений. Я решил, что альтернативой было бы развернуть весь фрейм данных, который я успешно объединял, соединить один раз, а затем получить данные там, где я хочу, с помощью сочетания pl.coalesce и pl.join (вложенный Polars.col()).В моем случае это происходит быстрее, чем последовательные соединения, поскольку корзины становятся больше, но Мне интересно, существует ли лучший (более быстрый и более эффективный по памяти) способ достижения это.
В реальной жизни я могу выполнять следующие операции несколько раз, с большим количеством функций, большим количеством символов и большими корзинами.
(
df
.join(basket, on='symbol', how='left')
# I've put an iterative function to do the successive joins when needed, assume more than 2 joins in real life
.join(df.select('date','symbol', col('price').name.suffix('_1')),
left_on = ['date', 'symbol_1'],
right_on = ['date', 'symbol'],
how='left',
)
.join(df.select('date','symbol', col('price').name.suffix('_2')),
left_on = ['date', 'symbol_2'],
right_on = ['date', 'symbol'],
how='left',
)
)
df_pivot = (
# I normally use the lazyframe pivot implementation to wrok with lazyframe
df.pivot(index='date', on='symbol', values='price')
)
(
df.join(basket, on="symbol", how="left")
# alternative to the successive joins
.join(
df_pivot.select('date', pl.exclude('date').name.suffix('_price_to_drop')),
on="date",
how="left",
)
.with_columns(
*[
pl.coalesce(
pl.when(col(f'symbol_{i}')==symbol)
.then(col(f'{symbol}_price_to_drop'))
for symbol in list_symbols
).alias(f'price_{i}')
for i in [1,2]
]
)
.select(pl.exclude("^.*to_drop$"))
)
Обратите внимание, что я обычно работаю с ленивыми фреймами. В приведенном выше примере это не так.
У меня есть большой набор данных, и мне нужно выполнить несколько последовательных медленных объединений. Я решил, что альтернативой было бы развернуть весь фрейм данных, который я успешно объединял, соединить один раз, а затем получить данные там, где я хочу, с помощью сочетания pl.coalesce и pl.join (вложенный Polars.col()).В моем случае это происходит быстрее, чем последовательные соединения, поскольку корзины становятся больше, но [b]Мне интересно, существует ли лучший (более быстрый и более эффективный по памяти) способ достижения это.[/b] В реальной жизни я могу выполнять следующие операции несколько раз, с большим количеством функций, большим количеством символов и большими корзинами. [code]import polars as pl from polars import col from vega_datasets import data
basket = pl.DataFrame( { "MSFT": ["AMZN", "GOOG"], "AMZN": ["MSFT", "GOOG"], "GOOG": ["AAPL", "IBM"], "IBM": ["AMZN", "AAPL"], "AAPL": ["AMZN", "IBM"], } ).transpose( include_header=True, header_name="symbol", column_names=["symbol_1", "symbol_2"], ) [/code] [list] [*]Последовательные объединения [/list] [code]( df .join(basket, on='symbol', how='left') # I've put an iterative function to do the successive joins when needed, assume more than 2 joins in real life .join(df.select('date','symbol', col('price').name.suffix('_1')), left_on = ['date', 'symbol_1'], right_on = ['date', 'symbol'], how='left', ) .join(df.select('date','symbol', col('price').name.suffix('_2')), left_on = ['date', 'symbol_2'], right_on = ['date', 'symbol'], how='left', ) ) [/code] [list] [*]Разворот, объединение, вложенный столбец (объединение + когда) [/list] [code]df_pivot = ( # I normally use the lazyframe pivot implementation to wrok with lazyframe df.pivot(index='date', on='symbol', values='price') )
( df.join(basket, on="symbol", how="left") # alternative to the successive joins .join( df_pivot.select('date', pl.exclude('date').name.suffix('_price_to_drop')), on="date", how="left", ) .with_columns( *[ pl.coalesce( pl.when(col(f'symbol_{i}')==symbol) .then(col(f'{symbol}_price_to_drop')) for symbol in list_symbols ).alias(f'price_{i}') for i in [1,2] ] ) .select(pl.exclude("^.*to_drop$")) ) [/code] Обратите внимание, что я обычно работаю с ленивыми фреймами. В приведенном выше примере это не так.