2014-02-15 13 views
102

ein Datenrahmen mit einer Spalte „BoolCol“ Da wir die Indizes der Datenrahmen finden möchten, in denen die Werte für „BoolCol“ == truePython Pandas: Index der Zeilen Erhalten Sie die Spalte bestimmten Wert übereinstimmt

I zur Zeit haben die Iterieren Weg, es zu tun, die perfekt funktioniert:

for i in range(100,3000): 
    if df.iloc[i]['BoolCol']== True: 
     print i,df.iloc[i]['BoolCol'] 

Aber das ist nicht der Weg des richtigen Panda, es zu tun. Nach einigen Recherchen, ich bin derzeit mit diesem Code:

df[df['BoolCol'] == True].index.tolist() 

Dies mir eine Liste von Indizes gibt, aber sie nicht übereinstimmen, wenn ich sie überprüfen, indem Sie:

df.iloc[i]['BoolCol'] 

Das Ergebnis ist eigentlich falsch !!

Welches wäre die richtige Pandas-Methode?

Antwort

173

df.iloc[i] gibt die ith Zeile df zurück. i bezieht sich nicht auf das Indexlabel, i ist ein 0-basierter Index.

Im Gegensatz dazu das Attribut index kehren aktuelle Indexetikett, nicht numerisch Zeilenindizes:

df.index[df['BoolCol'] == True].tolist() 

oder äquivalent

df.index[df['BoolCol']].tolist() 

Sie den Unterschied ganz deutlich sehen kann durch das Spiel Ein DataFrame mit ein "ungewöhnlicher" Index:

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] 

Wenn Sie den Index,

In [56]: idx = df.index[df['BoolCol']] 

In [57]: idx 
Out[57]: Int64Index([10, 40, 50], dtype='int64') 

dann können Sie wählen die Zeilen mit loc statt iloc verwenden möchten:

In [58]: df.loc[idx] 
Out[58]: 
    BoolCol 
10 True 
40 True 
50 True 

[3 rows x 1 columns] 

Beachten Sie, dass loc können auch akzeptieren, boolean Arrays:

In [55]: df.loc[df['BoolCol']] 
Out[55]: 
    BoolCol 
10 True 
40 True 
50 True 

[3 rows x 1 columns] 

Wenn Sie eine boolean-Array haben, mask und Ordnungsindexwerte benötigen, können Sie sie mit np.flatnonzero berechnen:

In [110]: np.flatnonzero(df['BoolCol']) 
Out[112]: array([0, 3, 4]) 

Verwenden df.iloc zum Auswählen von Zeilen nach Ordnungsindex:

In [113]: df.iloc[np.flatnonzero(df['BoolCol'])] 
Out[113]: 
    BoolCol 
10 True 
40 True 
50 True 
+6

Noch eine andere Art und Weise zu tun, 'df.query ('BoolCol')'. –

+2

Ich weiß, das ist alt, aber ich frage mich, ob es eine einfache Möglichkeit gibt, die 0-basierten Indexnummern aus einer Abfrage zu erhalten. Ich brauche die Iloc-Nummern, weil ich einige Zeilen vor und nach einer Zeile auswählen möchte, die eine bestimmte Bedingung erfüllen. Mein Plan war also, die 0-Indizes von Zeilen zu erhalten, die die Bedingung erfüllen, und dann Slices für die Verwendung in iloc() zu erstellen. Das einzige, was ich sehe, ist get_loc, aber es kann kein Array nehmen. – sheridp

+1

@sheridp: Wenn Sie eine boolesche Maske haben, können Sie die Ordinalindizes finden, wo die 'Maske'' True' ist, indem Sie 'np.flatnonzero' verwenden. Ich habe den Beitrag oben bearbeitet, um zu zeigen, was ich meine. – unutbu

6

Kann mit numpy erfolgen where() Funktion:

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 

Obwohl Sie für ein Spiel brauchen Index nicht immer, aber einhüllen, wenn Sie brauchen:

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'] 
Verwandte Themen