by Anonymous » 24 Dec 2024, 09:02
Ich habe einen großen Datensatz und muss mehrere aufeinanderfolgende Verknüpfungen durchführen, die langsam sind. Ich dachte, eine Alternative bestünde darin, den gesamten Datenrahmen, den ich erfolgreich zusammengeführt habe, zu entpivotieren, ihn einmal zu verbinden und dann die Daten mit einer Mischung aus pl.coalesce und pl.join (Nested polars.col()) an die gewünschte Stelle zu bringen.Für meinen Anwendungsfall ist dies schneller als die aufeinanderfolgenden Verknüpfungen, wenn die Körbe größer werden, aber
Ich habe mich gefragt, ob es einen besseren (schnelleren, speichereffizienteren) Weg gibt, dies zu erreichen Dies.
Im wirklichen Leben führe ich die folgenden Operationen möglicherweise mehrmals aus, für mehr Funktionen, mehr Symbole und größere Körbe.
import polars as pl
from polars import col
from vega_datasets import data
df = pl.from_pandas(data.stocks())
list_symbols = df.select(col('symbol').unique()).to_series().to_list()
"""
[
"IBM",
"MSFT",
"AAPL",
"AMZN",
"GOOG"
]
"""
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"],
)
- Aufeinanderfolgende Verknüpfungen
(
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',
)
)
- Entpivotieren, verbinden, verschachtelte Spalte (zusammenfügen + wann)
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$"))
)
Beachten Sie, dass ich normalerweise mit Lazyframes arbeite. Dies ist im obigen Beispiel nicht der Fall.
Ich habe einen großen Datensatz und muss mehrere aufeinanderfolgende Verknüpfungen durchführen, die langsam sind. Ich dachte, eine Alternative bestünde darin, den gesamten Datenrahmen, den ich erfolgreich zusammengeführt habe, zu entpivotieren, ihn einmal zu verbinden und dann die Daten mit einer Mischung aus pl.coalesce und pl.join (Nested polars.col()) an die gewünschte Stelle zu bringen.Für meinen Anwendungsfall ist dies schneller als die aufeinanderfolgenden Verknüpfungen, wenn die Körbe größer werden, aber [b]Ich habe mich gefragt, ob es einen besseren (schnelleren, speichereffizienteren) Weg gibt, dies zu erreichen Dies.[/b]
Im wirklichen Leben führe ich die folgenden Operationen möglicherweise mehrmals aus, für mehr Funktionen, mehr Symbole und größere Körbe.
import polars as pl
from polars import col
from vega_datasets import data
df = pl.from_pandas(data.stocks())
list_symbols = df.select(col('symbol').unique()).to_series().to_list()
"""
[
"IBM",
"MSFT",
"AAPL",
"AMZN",
"GOOG"
]
"""
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"],
)
[list]
[*]Aufeinanderfolgende Verknüpfungen
[/list]
(
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',
)
)
[list]
[*]Entpivotieren, verbinden, verschachtelte Spalte (zusammenfügen + wann)
[/list]
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$"))
)
Beachten Sie, dass ich normalerweise mit Lazyframes arbeite. Dies ist im obigen Beispiel nicht der Fall.