df =
Col1 Col2 Col3
1 nan 4
2 5 4
3 3 nan
In Anbetracht des Datenrahmens df
möchte ich einen neuen Datenrahmen df2
erhalten, der nan
nicht in der Spalte Col2
enthält. Dies ist das erwartete Ergebnis: df2 =
Col1 Col2 Col3
2 5 4
3 3 nan
Ich weiß, dass es möglich ist, pandas.isnull
und dropna
zu verwenden. Wie kann jedoch nur eine bestimmte Spalte angegeben werden, auf die die Filterung angewendet werden soll?
sie können die DataFrame.dropna()
-Methode verwenden:
In [202]: df.dropna(subset=['Col2'])
Out[202]:
Col1 Col2 Col3
1 2 5.0 4.0
2 3 3.0 NaN
oder (in diesem Fall) weniger idiomatic Series.notnull () :
In [204]: df.loc[df.Col2.notnull()]
Out[204]:
Col1 Col2 Col3
1 2 5.0 4.0
2 3 3.0 NaN
oder mit DataFrame.query () Methode:
In [205]: df.query("Col2 == Col2")
Out[205]:
Col1 Col2 Col3
1 2 5.0 4.0
2 3 3.0 NaN
numexpr
Lösung:
In [241]: import numexpr as ne
In [242]: col = df.Col2
In [243]: df[ne.evaluate("col == col")]
Out[243]:
Col1 Col2 Col3
1 2 5.0 4.0
2 3 3.0 NaN
Verwenden Sie dropna
:
df = df.dropna(subset=['Col2'])
print (df)
Col1 Col2 Col3
1 2 5.0 4.0
2 3 3.0 NaN
Eine andere Lösung - boolean indexing
mit notnull
:
df = df[df['Col2'].notnull()]
print (df)
Col1 Col2 Col3
1 2 5.0 4.0
2 3 3.0 NaN
Was ist das Gleiche wie:
df = df[~df['Col2'].isnull()]
print (df)
Col1 Col2 Col3
1 2 5.0 4.0
2 3 3.0 NaN
Verwenden von numpy
s isnan
zum Maskieren und Erstellen eines neuen Datenrahmens
m = ~np.isnan(df.Col2.values)
pd.DataFrame(df.values[m], df.index[m], df.columns)
Col1 Col2 Col3
1 2.0 5.0 4.0
2 3.0 3.0 NaN
Zeitliche Koordinierung
Größere Daten
np.random.seed([3,1415])
df = pd.DataFrame(np.random.choice([np.nan, 1], size=(10000, 10))).add_prefix('Col')
%%timeit
m = ~np.isnan(df.Col2.values)
pd.DataFrame(df.values[m], df.index[m], df.columns)
1000 loops, best of 3: 326 µs per loop
%timeit df.query("Col2 == Col2")
1000 loops, best of 3: 1.48 ms per loop
%timeit df.loc[df.Col2.notnull()]
1000 loops, best of 3: 417 µs per loop
%timeit df[~df['Col2'].isnull()]
1000 loops, best of 3: 385 µs per loop
%timeit df.dropna(subset=['Col2'])
1000 loops, best of 3: 913 µs per loop
Wenn Sie die Anzahl der Nans vor dem Löschen Ihrer Spalten zählen und grafisch darstellen möchten
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
cols = df.columns
nans = [df[col].isna().sum() for col in cols]
sns.set(font_scale=1.1)
ax = sns.barplot(cols, nans, palette='hls', log=False)
ax.set(xlabel='Feature', ylabel='Number of NaNs', title='Number of NaNs per feature')
for p, uniq in Zip(ax.patches, nans):
height = p.get_height()
ax.text(p.get_x()+p.get_width()/2.,
height + 10,
uniq,
ha="center")
ax.set_xticklabels(ax.get_xticklabels(),rotation=90)
plt.show()