Ik heb de volgende tabel:
Opmerking: zowel NSRCODE als PBL_AWI zijn indexen
Opmerking: de kolom % van het gebied zou zijn ingevuld, maar heb dit nog niet gedaan.
NSRCODE PBL_AWI Area % Of Area
CM BONS 44705.492941
BTNN 253854.591990
FONG 41625.590370
FONS 16814.159680
Lake 57124.819333
River 1603.906642
SONS 583958.444751
STNN 45603.837177
clearcut 106139.013930
disturbed 127719.865675
lowland 118795.578059
upland 2701289.270193
LBH BFNN 289207.169650
BONS 9140084.716743
BTNI 33713.160390
BTNN 19748004.789040
FONG 1687122.469691
FONS 5169959.591270
FTNI 317251.976160
FTNN 6536472.869395
Lake 258046.508310
River 44262.807900
SONS 4379097.677405
burn regen 744773.210860
clearcut 54066.756790
disturbed 597561.471686
lowland 12591619.141842
upland 23843453.638117
Hoe filter ik een item uit de “PBL_AWI”-index?
Ik wil bijvoorbeeld [‘Lake’, ‘River’, ‘Upland’]
. behouden
Antwoord 1, autoriteit 100%
Je kunt get_level_values
gebruiken in combinatie met Boolean slicing.
In [50]:
print df[np.in1d(df.index.get_level_values(1), ['Lake', 'River', 'Upland'])]
Area
NSRCODE PBL_AWI
CM Lake 57124.819333
River 1603.906642
LBH Lake 258046.508310
River 44262.807900
Hetzelfde idee kan op veel verschillende manieren worden uitgedrukt, zoals df[df.index.get_level_values('PBL_AWI').isin(['Lake', 'River', 'Upland'])]
Houd er rekening mee dat u 'Upland'
in uw gegevens heeft in plaats van 'Upland'
Antwoord 2, autoriteit 42%
Een andere (misschien schonere) manier zou deze kunnen zijn:
print(df[df.index.isin(['Lake', 'River', 'Upland'], level=1)])
De parameter level
specificeert het indexnummer (beginnend met 0) of indexnaam (hier: level='PBL_AWI'
)
Antwoord 3, autoriteit 7%
Ook (van hier):
def filter_by(df, constraints):
"""Filter MultiIndex by sublevels."""
indexer = [constraints[name] if name in constraints else slice(None)
for name in df.index.names]
return df.loc[tuple(indexer)] if len(df.shape) == 1 else df.loc[tuple(indexer),]
pd.Series.filter_by = filter_by
pd.DataFrame.filter_by = filter_by
… te gebruiken als
df.filter_by({'PBL_AWI' : ['Lake', 'River', 'Upland']})
(niet getest met panelen en elementen met een hogere dimensie, maar ik verwacht wel dat het werkt)
Antwoord 4, autoriteit 4%
df.filter(regex=…,axis=…)is nog beknopter, omdat het werkt op zowel index=0 als kolom=1 as. U hoeft zich geen zorgen te maken over niveaus en u kunt lui zijn met regex. Compleet voorbeeld voor filter op index:
df.filter(regex='Lake|River|Upland',axis=0)
als je het transponeert en probeert te filteren op kolommen (standaard as=1), werkt het ook:
df.T.filter(regex='Lake|River|Upland')
Nu kun je met regex ook gemakkelijk hoofdletters oplossen met Upland:
upland = re.compile('Upland', re.IGNORECASE)
df.filter(regex=upland ,axis=0)
Dit is het commando om bovenstaande invoertabel te lezen:
df = pd.read_csv(io.StringIO(inpute_table), sep="\s{2,}").set_index(['NSRCODE', 'PBL_AWI'])
Antwoord 5, autoriteit 2%
Een eenvoudigere aanpak met behulp van .loc
zou zijn
df.loc[(slice(None),['Lake', 'River', 'Upland'])]
slice(None)
betekent geen filtering op de index op het eerste niveau. We kunnen de index op het tweede niveau filteren met behulp van een lijst met waarden ['Lake', 'River', 'Upland']
Antwoord 6
Dit is een antwoord op een kleine variant van de gestelde vraag die iemand anders misschien wat tijd kan besparen. Als u op zoek bent naar een wildcard-type overeenkomst met een label waarvan u de exacte waarde niet weet, kunt u zoiets als dit gebruiken:
q_labels = [ label for label in df.index.levels[1] if label.startswith('Q') ]
new_df = df[ df.index.isin(q_labels, level=1) ]