Gitt en DataFrame med en kolonne "BoolCol", ønsker vi å finne indeksene til DataFrame der verdiene for "BoolCol" == True
Jeg har for øyeblikket den itererende måten å gjøre det på, som fungerer perfekt:
for i in range(100,3000):
if df.iloc[i]['BoolCol']== True:
print i,df.iloc[i]['BoolCol']
Men dette er ikke den riktige pandaens måte å gjøre det på. Etter litt forskning bruker jeg for øyeblikket denne koden:
df[df['BoolCol'] == True].index.tolist()
Denne gir meg en liste over indekser, men de stemmer ikke overens når jeg sjekker dem ved å gjøre:
df.iloc[i]['BoolCol']
Resultatet er faktisk False!!!
Hvilken ville være den riktige Panda-måten å gjøre dette på?
df.iloc[i]
returnerer den ith
raden av df
. i
refererer ikke til indeksetiketten, i
er en 0-basert indeks.
Derimot returnerer attributtet index
faktiske indeksetiketter, ikke numeriske radindekser:
df.index[df['BoolCol'] == True].tolist()
eller tilsvarende,
df.index[df['BoolCol']].tolist()
Du kan se forskjellen ganske tydelig ved å spille med en DataFrame med en ikke-standardindeks som ikke er lik radens numeriske posisjon:
df = pd.DataFrame({'BoolCol': [True, False, False, True, True]},
index=[10,20,30,40,50])
In [53]: df
Out[53]:
BoolCol
10 True
20 False
30 False
40 True
50 True
[5 rows x 1 columns]
In [54]: df.index[df['BoolCol']].tolist()
Out[54]: [10, 40, 50]
Hvis du vil bruke indeksen,
In [56]: idx = df.index[df['BoolCol']]
In [57]: idx
Out[57]: Int64Index([10, 40, 50], dtype='int64')
så kan du velge radene ved hjelp av loc
i stedet for iloc
:
In [58]: df.loc[idx]
Out[58]:
BoolCol
10 True
40 True
50 True
[3 rows x 1 columns]
Merk at loc
også kan akseptere boolske matriser:
In [55]: df.loc[df['BoolCol']]
Out[55]:
BoolCol
10 True
40 True
50 True
[3 rows x 1 columns]
Hvis du har en boolsk matrise, mask
, og trenger ordinale indeksverdier, kan du beregne dem ved hjelp av np.flatnonzero
:
In [110]: np.flatnonzero(df['BoolCol'])
Out[112]: array([0, 3, 4])
Bruk df.iloc
for å velge rader etter ordinal indeks:
In [113]: df.iloc[np.flatnonzero(df['BoolCol'])]
Out[113]:
BoolCol
10 True
40 True
50 True
Kan gjøres ved hjelp av funksjonen numpy where():
import pandas as pd
import numpy as np
In [716]: df = pd.DataFrame({"gene_name": ['SLC45A1', 'NECAP2', 'CLIC4', 'ADC', 'AGBL4'] , "BoolCol": [False, True, False, True, True] },
index=list("abcde"))
In [717]: df
Out[717]:
BoolCol gene_name
a False SLC45A1
b True NECAP2
c False CLIC4
d True ADC
e True AGBL4
In [718]: np.where(df["BoolCol"] == True)
Out[718]: (array([1, 3, 4]),)
In [719]: select_indices = list(np.where(df["BoolCol"] == True)[0])
In [720]: df.iloc[select_indices]
Out[720]:
BoolCol gene_name
b True NECAP2
d True ADC
e True AGBL4
Selv om du ikke alltid trenger indeks for en match, men incase hvis du trenger det:
In [796]: df.iloc[select_indices].index
Out[796]: Index([u'b', u'd', u'e'], dtype='object')
In [797]: df.iloc[select_indices].index.tolist()
Out[797]: ['b', 'd', 'e']
Først kan du sjekke query
når målkolonnen er av typen bool
(PS: om hvordan du bruker den, se link ).
df.query('BoolCol')
Out[123]:
BoolCol
10 True
40 True
50 True
Etter at vi har filtrert den opprinnelige df etter den boolske kolonnen, kan vi velge indeksen .
df=df.query('BoolCol')
df.index
Out[125]: Int64Index([10, 40, 50], dtype='int64')
Også pandaer har nonzero
, vi velger bare posisjonen til True
-raden og bruker den til å skive DataFrame
eller index
.
df.index[df.BoolCol.nonzero()[0]]
Out[128]: Int64Index([10, 40, 50], dtype='int64')