Python Pandas:获取列匹配特定值的行的索引
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/21800169/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python Pandas: Get index of rows which column matches certain value
提问by I want badges
Given a DataFrame with a column "BoolCol", we want to find the indexes of the DataFrame in which the values for "BoolCol" == True
给定一个带有“BoolCol”列的 DataFrame,我们想要找到“BoolCol”的值 == True 的 DataFrame 的索引
I currently have the iterating way to do it, which works perfectly:
我目前有迭代方式来做到这一点,它完美地工作:
for i in range(100,3000):
    if df.iloc[i]['BoolCol']== True:
         print i,df.iloc[i]['BoolCol']
But this is not the correct panda's way to do it. After some research, I am currently using this code:
但这不是正确的熊猫方式。经过一番研究,我目前正在使用此代码:
df[df['BoolCol'] == True].index.tolist()
This one gives me a list of indexes, but they dont match, when I check them by doing:
这个给了我一个索引列表,但当我通过以下方式检查它们时,它们不匹配:
df.iloc[i]['BoolCol']
The result is actually False!!
结果居然是假的!!
Which would be the correct Pandas way to do this?
哪个是 Pandas 的正确方法?
采纳答案by unutbu
df.iloc[i]returns the ithrow of df. idoes not refer to the index label, iis a 0-based index.
df.iloc[i]返回 的ith行df。i不引用索引标签,i是一个从0开始的索引。
In contrast, the attribute indexreturns actual index labels, not numeric row-indices:
相反,该属性index返回实际索引标签,而不是数字行索引:
df.index[df['BoolCol'] == True].tolist()
or equivalently,
或等效地,
df.index[df['BoolCol']].tolist()
You can see the difference quite clearly by playing with a DataFrame with a non-default index that does not equal to the row's numerical position:
通过使用具有不等于行的数字位置的非默认索引的 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]
If you want to use the index,
如果要使用索引,
In [56]: idx = df.index[df['BoolCol']]
In [57]: idx
Out[57]: Int64Index([10, 40, 50], dtype='int64')
then you can select the rows using locinstead of iloc:
那么您可以使用loc而不是选择行iloc:
In [58]: df.loc[idx]
Out[58]: 
   BoolCol
10    True
40    True
50    True
[3 rows x 1 columns]
Note that loccan also accept boolean arrays:
请注意,loc也可以接受布尔数组:
In [55]: df.loc[df['BoolCol']]
Out[55]: 
   BoolCol
10    True
40    True
50    True
[3 rows x 1 columns]
If you have a boolean array, mask, and need ordinal index values, you can compute them using np.flatnonzero:
如果您有一个布尔数组 ,mask并且需要序数索引值,您可以使用np.flatnonzero以下方法计算它们:
In [110]: np.flatnonzero(df['BoolCol'])
Out[112]: array([0, 3, 4])
Use df.ilocto select rows by ordinal index:
用于df.iloc按序数索引选择行:
In [113]: df.iloc[np.flatnonzero(df['BoolCol'])]
Out[113]: 
   BoolCol
10    True
40    True
50    True
回答by Surya
Can be done using numpy where() function:
可以使用 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
Though you don't always need index for a match, but incase if you need:
虽然您并不总是需要匹配的索引,但如果您需要:
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']
回答by YOBEN_S
First you may check querywhen the target column is type bool(PS: about how to use it please check link)
首先您可以检查query目标列何时输入bool(PS:有关如何使用它请检查链接)
df.query('BoolCol')
Out[123]: 
    BoolCol
10     True
40     True
50     True
After we filter the original df by the Boolean column we can pick the index .
在我们通过布尔列过滤原始 df 之后,我们可以选择索引。
df=df.query('BoolCol')
df.index
Out[125]: Int64Index([10, 40, 50], dtype='int64')
Also pandas have nonzero, we just select the positionof Truerow and using it slice the DataFrameor index
也有大熊猫nonzero,我们只需选择位置的True一排并用它切片DataFrame或index
df.index[df.BoolCol.nonzero()[0]]
Out[128]: Int64Index([10, 40, 50], dtype='int64')
回答by Ben Druitt
Simple way is to reset the index of the DataFrame prior to filtering:
简单的方法是在过滤之前重置 DataFrame 的索引:
df_reset = df.reset_index()
df_reset[df_reset['BoolCol']].index.tolist()
Bit hacky, but it's quick!
有点hacky,但它很快!
回答by Carson
I extended this question that is how to gets the row, columnand valueof all matches value?
我扩展了这个问题,即如何获取row,column以及value所有匹配项的值?
here is solution:
这是解决方案:
import pandas as pd
import numpy as np
def search_coordinate(df_data: pd.DataFrame, search_set: set) -> list:
    nda_values = df_data.values
    tuple_index = np.where(np.isin(nda_values, [e for e in search_set]))
    return [(row, col, nda_values[row][col]) for row, col in zip(tuple_index[0], tuple_index[1])]
if __name__ == '__main__':
    test_datas = [['cat', 'dog', ''],
                  ['goldfish', '', 'kitten'],
                  ['Puppy', 'hamster', 'mouse']
                  ]
    df_data = pd.DataFrame(test_datas)
    print(df_data)
    result_list = search_coordinate(df_data, {'dog', 'Puppy'})
    print(f"\n\n{'row':<4} {'col':<4} {'name':>10}")
    [print(f"{row:<4} {col:<4} {name:>10}") for row, col, name in result_list]
Output:
输出:
          0        1       2
0       cat      dog        
1  goldfish           kitten
2     Puppy  hamster   mouse
row  col        name
0    1           dog
2    0         Puppy
回答by mbh86
If you want to use your dataframe object only once, use:
如果您只想使用数据框对象一次,请使用:
df['BoolCol'].loc[lambda x: x==True].index

