Как найти, какой столбец содержит определенное значение?

#python #pandas #dataframe

Вопрос:

У меня есть фрейм данных, подобный этому:

 test = pd.DataFrame({"id":[1,2,3,4],
                     "name_1":["peter","bobby","alex","chris"],
                     "name_1_flag":["real","fake","fake","real"],
                     "name_2":["hector","abi","henrik","miko"],
                     "name_2_flag":["fake","real","fake","fake"],
                     "name_3":["hans","khan","will","than"],
                     "name_3_flag":["fake","fake","real","fake"]})

   id name_1 name_1_flag  name_2 name_2_flag name_3 name_3_flag
0   1  peter        real  hector        fake   hans        fake
1   2  bobby        fake     abi        real   khan        fake
2   3   alex        fake  henrik        fake   will        real
3   4  chris        real    miko        fake   than        fake
 

Как я могу найти кортеж строк / столбцов, в котором есть слово «real».

Оптимально, чтобы на выходе был массив или ряд, подобный этому:

     col_index
0           3
1           5
2           7
3           3
 

Ответ №1:

Используйте np.где:

 test["col_index"] = np.where(test.eq("real"))[1]   1
print(test)
 

Вывод

    id name_1 name_1_flag  name_2 name_2_flag name_3 name_3_flag  col_index
0   1  peter        real  hector        fake   hans        fake          3
1   2  bobby        fake     abi        real   khan        fake          5
2   3   alex        fake  henrik        fake   will        real          7
3   4  chris        real    miko        fake   than        fake          3
 

Ответ №2:

Решения:

Попробуйте np.argmax :

 >>> np.argmax(test.eq('real').to_numpy(), axis=1)   1
array([3, 5, 7, 3], dtype=int64)
>>> 
 

— Или get_indexer :

 test.columns.get_indexer(test.eq('real').idxmax(axis=1))   1
 

Или .T.reset_index(drop=True) :

 test.T.reset_index(drop=True).eq('real').idxmax()   1
 

Превращение его в столбец:

np.argmax :

 test["col_index"] = np.argmax(test.eq('real').to_numpy(), axis=1)   1
 

Тот, который get_indexer :

 test["col_index"] = test.columns.get_indexer(test.eq('real').idxmax(axis=1))   1
 

.T :

 test["col_index"] = test.T.reset_index(drop=True).eq('real').idxmax()   1
 

Весь вывод:

    id name_1 name_1_flag  name_2 name_2_flag name_3 name_3_flag  col_index
0   1  peter        real  hector        fake   hans        fake          3
1   2  bobby        fake     abi        real   khan        fake          5
2   3   alex        fake  henrik        fake   will        real          7
3   4  chris        real    miko        fake   than        fake          3
 

Ответ №3:

Давайте попробуем с

 s = test.where(lambda x : x=='real').stack()
test['new'] = test.columns.get_indexer(s.index.get_level_values(1)) 1
test
Out[11]: 
   id name_1 name_1_flag  name_2 name_2_flag name_3 name_3_flag  new
0   1  peter        real  hector        fake   hans        fake    3
1   2  bobby        fake     abi        real   khan        fake    5
2   3   alex        fake  henrik        fake   will        real    7
3   4  chris        real    miko        fake   than        fake    3
 

Ответ №4:

Вы также можете использовать dot :

 print (test.eq("real").dot(range(test.columns.size)) 1)

0    3
1    5
2    7
3    3
dtype: int32