Python Pandas:获取列匹配特定值的行的索引

I w*_*ges 222 python indexing pandas

给定一个带有"BoolCol"列的DataFrame,我们想要找到DataFrame的索引,其中"BoolCol"的值== True

我目前有迭代的方式来做到这一点,它完美地工作:

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

但这不是正确的熊猫方式.经过一些研究,我目前正在使用此代码:

df[df['BoolCol'] == True].index.tolist()
Run Code Online (Sandbox Code Playgroud)

这个给了我一个索引列表,但是当我通过执行以下操作检查它们时它们不匹配:

df.iloc[i]['BoolCol']
Run Code Online (Sandbox Code Playgroud)

结果实际上是假的!!

这是正确的熊猫方式吗?

unu*_*tbu 356

df.iloc[i]返回ithdf.i不引用索引标签,i是一个基于0的索引.

相反,该属性index返回实际的索引标签,而不是数字行索引:

df.index[df['BoolCol'] == True].tolist()
Run Code Online (Sandbox Code Playgroud)

或等效地,

df.index[df['BoolCol']].tolist()
Run Code Online (Sandbox Code Playgroud)

通过使用带有"异常"索引的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]
Run Code Online (Sandbox Code Playgroud)

如果要使用索引,

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

In [57]: idx
Out[57]: Int64Index([10, 40, 50], dtype='int64')
Run Code Online (Sandbox Code Playgroud)

然后你可以使用loc而不是iloc:

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

[3 rows x 1 columns]
Run Code Online (Sandbox Code Playgroud)

注意,loc也可以接受布尔数组:

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

[3 rows x 1 columns]
Run Code Online (Sandbox Code Playgroud)

如果您有一个布尔数组,mask并且需要序数索引值,则可以使用np.flatnonzero以下方法计算它们:

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

用于df.iloc按顺序索引选择行:

In [113]: df.iloc[np.flatnonzero(df['BoolCol'])]
Out[113]: 
   BoolCol
10    True
40    True
50    True
Run Code Online (Sandbox Code Playgroud)

  • 另一种方法是做`df.query('BoolCol')`. (9认同)
  • 你的建议`indices = np.flatnonzero(df [col_name] == category_name)`确切地告诉我问题的标题是什么,这在互联网上很难找到. (6认同)
  • 我知道这是旧的,但我想知道是否有一种简单的方法可以从查询中获取基于0的索引号.我需要iloc数字,因为我想在符合特定条件的行之前和之后选择一些行.所以我的计划是让行的0指数满足条件,然后创建切片以便在iloc()中使用.我唯一看到的是get_loc,但它不能采用数组. (3认同)
  • @sheridp:如果您具有布尔掩码,则可以使用np.flatnonzero来找到掩码为True的顺序索引。我已经编辑了上面的帖子以显示我的意思。 (3认同)

Sur*_*rya 21

可以使用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
Run Code Online (Sandbox Code Playgroud)

虽然您并不总是需要匹配索引,但如果您需要,请填写:

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']
Run Code Online (Sandbox Code Playgroud)


mbh*_*h86 17

如果您只想使用数据框对象一次,请使用:

df['BoolCol'].loc[lambda x: x==True].index
Run Code Online (Sandbox Code Playgroud)


WeN*_*Ben 5

首先你可以检查query目标列何时为type bool (PS:如何使用请查看链接

df.query('BoolCol')
Out[123]: 
    BoolCol
10     True
40     True
50     True
Run Code Online (Sandbox Code Playgroud)

在我们通过布尔列过滤原始 df 后,我们可以选择索引。

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

pandas 也有nonzero,我们只需选择行的位置True并使用它来切片DataFrameindex

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


小智 5

简单的方法是在过滤之前重置 DataFrame 的索引:

df_reset = df.reset_index()
df_reset[df_reset['BoolCol']].index.tolist()
Run Code Online (Sandbox Code Playgroud)

有点hacky,但是很快!