pandas 2.2 è stato rilasciato il 22 gennaio 2024. Diamo un’occhiata alle novità introdotte da questa versione e a come ci aiuterà a migliorare i carichi di lavoro dei nostri panda. Include una serie di miglioramenti che miglioreranno l’esperienza dell’utente.
Pandas 2.2 ha apportato alcuni miglioramenti aggiuntivi che si basano sull’ecosistema Apache Arrow. Inoltre, abbiamo aggiunto deprecazioni per le modifiche necessarie per rendere Copy-on-Write l’impostazione predefinita in Pandas 3.0. Scopriamo cosa significa questo per te. Analizzeremo nel dettaglio le novità più importanti.
Faccio parte del team principale dei panda. Sono un ingegnere open source per Arrotolato dove lavoro su Dask, incluso il miglioramento dell’integrazione dei panda.
Supporto PyArrow migliorato
Abbiamo introdotto DataFrame supportato da PyArrow in Pandas 2.0 e da allora abbiamo continuato a migliorare l’integrazione per consentire un’integrazione perfetta nell’API Pandas. Pandas dispone di funzioni di accesso per determinati dtype che abilitano operazioni specializzate, come la funzione di accesso alle stringhe, che fornisce molti metodi di stringa. Storicamente, list e struct erano rappresentati come dtype oggetto NumPy, il che rendeva il lavoro con loro piuttosto complicato. Il backend Arrow dtype ora consente funzioni di accesso personalizzate per elenchi e strutture, il che rende molto più semplice il lavoro con questi oggetti.
Diamo un’occhiata ad un esempio:
import pyarrow as paseries = pd.Series(
(
{"project": "pandas", "version": "2.2.0"},
{"project": "numpy", "version": "1.25.2"},
{"project": "pyarrow", "version": "13.0.0"},
),
dtype=pd.ArrowDtype(
pa.struct((
("project", pa.string()),
("version", pa.string()),
))
),
)
Questa è una serie che contiene un dizionario in ogni riga. In precedenza, ciò era possibile solo con il dtype dell’oggetto NumPy e l’accesso agli elementi da queste righe richiedeva un’iterazione su di essi. IL struct
l’accessor ora consente l’accesso diretto a determinati attributi:
series.struct.field("project")0 pandas
1 numpy
2 pyarrow
Name: project, dtype: string(pyarrow)
La prossima versione porterà un CategoricalAccessor basato sui tipi Arrow.
Integrazione del driver Apache ADBC
Storicamente, i panda si affidavano a SqlAlchemy per leggere i dati da un database SQL. Ha funzionato in modo molto affidabile, ma è stato molto lento. Alchemy legge i dati in termini di righe, mentre Pandas ha un layout a colonne, che rende la lettura e lo spostamento dei dati in un DataFrame più lenti del necessario.
IL Driver ADBC dal progetto Apache Arrow consente agli utenti di leggere i dati in un layout a colonne, che apporta enormi miglioramenti delle prestazioni. Legge i dati e li memorizza in una tabella Arrow, che viene utilizzata per convertirli in un DataFrame panda. Puoi rendere questa conversione zero-copy, se imposti dtype_backend="pyarrow"
per read_sql
.
Diamo un’occhiata ad un esempio:
import adbc_driver_postgresql.dbapi as pg_dbapidf = pd.DataFrame(
(
(1, 2, 3),
(4, 5, 6),
),
columns=('a', 'b', 'c')
)
uri = "postgresql://postgres:postgres@localhost/postgres"
with pg_dbapi.connect(uri) as conn:
df.to_sql("pandas_table", conn, index=False)
# for round-tripping
with pg_dbapi.connect(uri) as conn:
df2 = pd.read_sql("pandas_table", conn)
Il driver ADBC attualmente supporta Postgres e Sqlite. Consiglierei a tutti di passare a questo driver se si utilizza Postgres, il driver è significativamente più veloce ed evita completamente il andata e ritorno attraverso gli oggetti Python, preservando così i tipi di database in modo più affidabile. Questa è la caratteristica che personalmente mi entusiasma di più.
Aggiunta case_when all’API panda
Passando da SQL a Panda, gli utenti spesso perdono la sintassi del caso in cui fornisce un modo semplice e pulito per creare nuove colonne in modo condizionale. panda 2.2 aggiunge un nuovo case_when
metodo, che è definito su una Serie. Funziona in modo simile a quello che fa SQL.
Diamo un’occhiata ad un esempio:
df = pd.DataFrame(dict(a=(1, 2, 3), b=(4, 5, 6)))default=pd.Series('default', index=df.index)
default.case_when(
caselist=(
(df.a == 1, 'first'),
(df.a.gt(1) & df.b.eq(5), 'second'),
),
)
Il metodo accetta un elenco di condizioni che vengono valutate in sequenza. Il nuovo oggetto viene quindi creato con i valori nelle righe in cui la condizione restituisce True. Il metodo dovrebbe semplificarci notevolmente la creazione di colonne condizionali.
Copia su scrittura
Copy-on-Write è stato inizialmente introdotto in Pandas 1.5.0. La modalità diventerà il comportamento predefinito con la versione 3.0, che si spera sia la prossima versione di Panda. Ciò significa che dobbiamo portare il nostro codice in uno stato in cui sia conforme alle regole Copy-on-Write. Pandas 2.2 ha introdotto avvisi di deprecazione per le operazioni che modificheranno il comportamento.
df = pd.DataFrame({"x": (1, 2, 3)})df("x")(df("x") > 1) = 100
Questo ora aumenterà a FutureWarning
.
FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!
You are setting values through chained assignment. Currently this works in certain cases, but when
using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to
update the original DataFrame or Series, because the intermediate object on which we are setting
values will behave as a copy. A typical example is when you are setting values in a column of a
DataFrame, like:df("col")(row_indexer) = value
Use `df.loc(row_indexer, "col") = values` instead, to perform the assignment in a single step and
ensure this keeps updating the original `df`.
scrissi un post precedente che fornisce maggiori dettagli su come è possibile migrare il codice e cosa aspettarsi. Esiste una modalità di avviso aggiuntiva per Copy-on-Write che genererà avvisi per tutti i casi che modificano il comportamento:
pd.options.mode.copy_on_write = "warn"
La maggior parte di questi avvisi sono solo rumore per la maggior parte degli utenti di Panda, motivo per cui sono nascosti dietro un’opzione.
pd.options.mode.copy_on_write = "warn"df = pd.DataFrame({"a": (1, 2, 3)})
view = df("a")
view.iloc(0) = 100
Ciò genererà un lungo avviso che spiega cosa cambierà:
FutureWarning: Setting a value on a view: behaviour will change in pandas 3.0.
You are mutating a Series or DataFrame object, and currently this mutation will
also have effect on other Series or DataFrame objects that share data with this
object. In pandas 3.0 (with Copy-on-Write), updating one Series or DataFrame object
will never modify another.
Il breve riassunto è: Aggiornamento view
non verrà mai aggiornato df
indipendentemente dall’operazione utilizzata. Molto probabilmente questo non è rilevante per la maggior parte.
Consiglierei di abilitare la modalità e di controllare brevemente gli avvisi, ma di non prestare loro troppa attenzione se sei a tuo agio nel non fare affidamento sull’aggiornamento di due oggetti diversi contemporaneamente.
Consiglierei di dare un’occhiata a guida alla migrazione per Copy-on-Write che spiega le modifiche necessarie in modo più dettagliato.
Aggiornamento alla nuova versione
Puoi installare la nuova versione di Panda con:
pip install -U pandas
O:
mamba install -c conda-forge pandas=2.2
Questo ti darà la nuova versione nel tuo ambiente.
Conclusione
Abbiamo esaminato un paio di miglioramenti che miglioreranno le prestazioni e l’esperienza dell’utente per alcuni aspetti di Pandas. Le nuove funzionalità più interessanti arriveranno in Pandas 3.0, dove Copy-on-Write sarà abilitato per impostazione predefinita.
Grazie per aver letto. Sentiti libero di contattarci per condividere i tuoi pensieri e feedback.
Fonte: towardsdatascience.com