536 Stimmen

Python Pandas: Index der Zeilen erhalten, in denen eine Spalte einen bestimmten Wert hat

Mit einem DataFrame mit einer Spalte "BoolCol" möchten wir die Indizes des DataFrames finden, in denen die Werte für "BoolCol" == True sind

Derzeit habe ich die iterative Methode, 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 richtige Weg, es mit pandas zu tun. Nach einiger Recherche verwende ich derzeit diesen Code:

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

Dieser gibt mir eine Liste von Indizes, aber sie passen nicht, wenn ich sie überprüfe, indem ich Folgendes tue:

df.iloc[i]['BoolCol']

Das Ergebnis ist tatsächlich False!!

Wie wäre der korrekte Weg, dies mit pandas zu tun?

777voto

unutbu Punkte 769083

df.iloc[i] gibt die ith Zeile von df zurück. i bezieht sich nicht auf das Index-Label, i ist ein nullbasierter Index.

Im Gegensatz dazu gibt das Attribut index tatsächliche Index-Labels zurück, keine numerischen Zeilenindizes:

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

oder gleichwertig,

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

Den Unterschied können Sie deutlich erkennen, wenn Sie mit einem DataFrame spielen, das einen nicht standardmäßigen Index hat, der nicht der numerischen Position der Zeile entspricht:

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 verwenden möchten,

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

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

dann können Sie die Zeilen mit loc anstelle von iloc auswählen:

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

[3 rows x 1 columns]

Beachten Sie, dass loc auch boolsche Arrays akzeptieren kann:

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

[3 rows x 1 columns]

Wenn Sie ein boolsches Array, mask haben und ordinalen Indexwerte benötigen, können Sie sie mit np.flatnonzero berechnen:

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

Verwenden Sie df.iloc, um Zeilen nach ordinalen Index auszuwählen:

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

49voto

Surya Punkte 9736

Kann mit der numpy where() Funktion gemacht werden:

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

Auch wenn man nicht immer einen Index für einen Treffer benötigt, aber falls Sie einen benötigen:

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

48voto

mbh86 Punkte 5898

Wenn Sie Ihr DataFrame-Objekt nur einmal verwenden möchten, verwenden Sie:

df['BoolCol'].loc[lambda x: x==True].index

5voto

BENY Punkte 302708

Zuerst sollten Sie query überprüfen, wenn die Zielspalte vom Typ bool ist (PS: wie man es verwendet, überprüfen Sie bitte den Link)

df.query('BoolCol')
Out[123]: 
    BoolCol
10     True
40     True
50     True

Nachdem wir das ursprüngliche DataFrame nach der Booleschen Spalte gefiltert haben, können wir den Index auswählen.

df=df.query('BoolCol')
df.index
Out[125]: Int64Index([10, 40, 50], dtype='int64')

Pandas hat auch nonzero, wir wählen einfach die Position der Zeile True aus und verwenden sie, um das DataFrame oder den Index zu schneiden

df.index[df.BoolCol.values.nonzero()[0]]
Out[128]: Int64Index([10, 40, 50], dtype='int64')

5voto

Ben Druitt Punkte 51

Eine einfache Möglichkeit besteht darin, den Index des DataFrames vor dem Filtern zurückzusetzen:

df_reset = df.reset_index()
df_reset[df_reset['BoolCol']].index.tolist()

Ein bisschen trickreich, aber es geht schnell!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X