2014-02-15 2 views
102

Учитывая DataFrame с колонкой «BoolCol», мы хотим, чтобы найти индексы в DataFrame, в которой значение для «BoolCol» == ПравдаPython Панда: Получить индекс строк, который соответствует определенному значению столбца

I в настоящее время есть итерация способ сделать это, который работает отлично:

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

Но это не путь Правильный панды, чтобы сделать это. После некоторых исследований, я в настоящее время с помощью этого кода:

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

Это один дает мне список индексов, но они не матч, когда я проверяю их, выполнив:

df.iloc[i]['BoolCol'] 

Результат фактически False !!

Какой будет правильный способ Pandas для этого?

ответ

173

df.iloc[i] возвращает ith ряд df. i не относится к метке индекса, i - это индекс, основанный на 0.

В отличие от этого, атрибут index возвращает фактический индекс метки, а не числовые строки-индексы:

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

или, что эквивалентно,

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

Вы можете увидеть разницу вполне ясно, играя с a DataFrame с «необычный» индекс:

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] 

Если вы хотите использовать индекс,

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

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

, то вы можете выбрать строки с помощью loc вместо iloc:

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

[3 rows x 1 columns] 

Обратите внимание, что loc также может принимать логические массивы:

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

[3 rows x 1 columns] 

Если у вас есть булево массив, mask, и нужны порядковые значения индекса, вы можете вычислить их с помощью np.flatnonzero:

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

Использования df.iloc для выбора строк по порядковым индексам:

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

Еще один способ сделать 'df.query ('BoolCol')'. –

+2

Я знаю, что это старо, но мне интересно, есть ли простой способ получить номера индексов на основе 0 из запроса. Мне нужны номера символов, потому что я хочу выбрать несколько строк до и после строки, удовлетворяющей определенному условию. Поэтому мой план состоял в том, чтобы получить 0-индексы строк, удовлетворяющих условию, а затем создать срезы для использования в iloc(). Единственное, что я вижу, это get_loc, но он не может принимать массив. – sheridp

+1

@sheridp: Если у вас есть булевая маска, вы можете найти порядковые индексы, где 'mask' является' True', используя 'np.flatnonzero'. Я отредактировал сообщение выше, чтобы показать, что я имею в виду. – unutbu

6

Может быть сделано с помощью NumPy, где функция():

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 

Хотя не всегда нужен индекс для матча, но упаковывают, если вам нужно:

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'] 
Смежные вопросы