groupby
könnte verwendet werden, um ein DataFrame in zwei aufzuteilen
Wenn das Ziel darin besteht, ein DataFrame in zwei DataFrames aufzuteilen, wobei eines die Länder zum Behalten enthält und das andere nicht, kann die durch den isin
-Aufruf erstellte boolesche Maske in einem groupby
-Aufruf verwendet werden, um das DataFrame in zwei aufzuteilen: haben und nicht haben.
df = pd.DataFrame({'country': ['US', 'UK', 'Germany', 'China'], 'value': range(4)})
countries_to_keep = ['UK', 'China']
df1, df2 = [g for _, g in df.groupby(df['country'].isin(countries_to_keep))]
![Ergebnis]()
eval()
könnte auch verwendet werden
query()
wird an anderer Stelle vorgeschlagen, um einen numerischen Ausdruck auszuwerten. Eine verwandte Methode ist eval()
. Es kann verwendet werden, um eine boolesche Maske zu erstellen und ein DataFrame zu filtern. Es kann mit anderen Masken verwendet werden, die vielleicht anderswo erstellt wurden, um ein flexibleres Filtern zu ermöglichen.
msk = df.eval('country in @countries_to_keep')
to_keep = df[msk] # in
not_keep = df[~msk] # not in
Ein besonderer Fall, in dem dies nützlich ist, besteht darin, wenn Sie eine einzelne Spalte unter Verwendung einer Bedingung filtern möchten. query
ist sehr speicherineffizient, da es eine Kopie des gefilterten Frames erstellt, der erneut für eine einzelne Spalte gefiltert werden muss, während loc
die Spalte in einem Schritt unter Verwendung einer booleschen Maske-Spaltenbezeichnungskombination auswählt. eval()
kann dasselbe tun.1
df = pd.DataFrame({'country': ['US', 'UK', 'Germany', 'China']*25000})
df[[f"col{i}" for i in range(50)]] = np.random.rand(100000, 50)
countries_to_keep = ['UK', 'China']
filtered = df.loc[df.eval('country==@countries_to_keep'), 'col1']
1 Ein Speicherprofilertest:
import numpy as np
import pandas as pd
%load_ext memory_profiler
df = pd.DataFrame({'country': ['US', 'UK', 'Germany', 'China']*25000})
df[[f"col{i}" for i in range(50)]] = np.random.rand(100000, 50)
countries_to_keep = ['UK', 'China']
%memit x = df.loc[df.eval('country==@countries_to_keep'), 'col1']
# peak memory: 157.28 MiB, increment: 5.44 MiB
%memit y = df.query('country==@countries_to_keep')['col1']
# peak memory: 195.39 MiB, increment: 38.11 MiB
%memit z = df.loc[df['country'].isin(countries_to_keep), 'col1']
# peak memory: 176.93 MiB, increment: 0.76 MiB