Python Pandas: Get index of rows which column matches certain value
给定一个带有"BoolCol"列的DataFrame,我们想要找到DataFrame的索引,其中"BoolCol"的值== True
我目前有迭代的方式来做到这一点,它完美地工作:
1 2 3 | for i in range(100,3000): if df.iloc[i]['BoolCol']== True: print i,df.iloc[i]['BoolCol'] |
但这不是正确的熊猫方式。
经过一些研究,我目前正在使用此代码:
1 | df[df['BoolCol'] == True].index.tolist() |
这个给了我一个索引列表,但是当我通过这样做检查它们时它们不匹配:
1 | df.iloc[i]['BoolCol'] |
结果实际上是假的!!
这是正确的熊猫方式吗?
相反,属性
1 | df.index[df['BoolCol'] == True].tolist() |
或等效地,
1 | df.index[df['BoolCol']].tolist() |
你可以通过使用DataFrame来清楚地看到差异
非默认索引,不等于行的数字位置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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] |
如果要使用索引,
1 2 3 4 | In [56]: idx = df.index[df['BoolCol']] In [57]: idx Out[57]: Int64Index([10, 40, 50], dtype='int64') |
然后您可以使用
1 2 3 4 5 6 7 8 | In [58]: df.loc[idx] Out[58]: BoolCol 10 True 40 True 50 True [3 rows x 1 columns] |
请注意,
1 2 3 4 5 6 7 8 | In [55]: df.loc[df['BoolCol']] Out[55]: BoolCol 10 True 40 True 50 True [3 rows x 1 columns] |
如果您有一个布尔数组
1 2 | In [110]: np.flatnonzero(df['BoolCol']) Out[112]: array([0, 3, 4]) |
使用
1 2 3 4 5 6 | In [113]: df.iloc[np.flatnonzero(df['BoolCol'])] Out[113]: BoolCol 10 True 40 True 50 True |
可以使用numpy where()函数完成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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 |
虽然您并不总是需要匹配索引,但如果您需要,请填写:
1 2 3 4 5 | 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'] |
首先,当目标列的类型为
1 2 3 4 5 6 | df.query('BoolCol') Out[123]: BoolCol 10 True 40 True 50 True |
在我们通过布尔列过滤原始df后,我们可以选择索引。
1 2 3 | df=df.query('BoolCol') df.index Out[125]: Int64Index([10, 40, 50], dtype='int64') |
还有pandas
1 2 | df.index[df.BoolCol.nonzero()[0]] Out[128]: Int64Index([10, 40, 50], dtype='int64') |
简单的方法是在过滤之前重置DataFrame的索引:
1 2 | df_reset = df.reset_index() df_reset[df_reset['BoolCol']].index.tolist() |
有点hacky,但它很快!