Отметьте первый ненулевой элемент в каждом столбце пандами

#python #pandas

Вопрос:

У меня есть большой фрейм данных, содержащий вероятности.

У меня также есть ряд, которые являются порогами.

Мне нужен результирующий DF, содержащий не более 1 в каждом столбце, который был бы элементом, в котором вероятности столбцов были ниже, чем вероятность соответствующего ряда в первый раз.

Т. е. если у меня есть DF

 A      B    C
0.1   0.7   0.01
0.3   0.05  0.9
0.01  0.01  0.02
 

и ряды со значениями 0,02, 0,06, 0,1
Тогда я хотел бы получить результат, такой как

 A    B    C
0    0    1
0    1    0
1    0    0
 

Я могу получить что-то вроде

 A    B    C
0    0    1
0    1    0
1    1    1
 

довольно легко, но мне нужно, чтобы в нем были только первые элементы, а не все.

Ответ №1:

Попробуйте с broadcasting :

Заданный ряд пороговых значений:

 threshold = pd.Series([0.02, 0.06, 0.1])
 
 m = df < threshold.values[:, None]
new_df = pd.DataFrame(
    m amp; (m.index.values[:, None] == m.idxmax().values),
    columns=df.columns,
    dtype=int
)
 
    A  B  C
0  0  0  1
1  0  1  0
2  1  0  0
 

Объяснение:

Найдите, где значения меньше значений массива:

 df < threshold.values[:, None]
 
        A      B      C
0  False  False   True
1  False   True  False
2   True   True   True
 

Затем используйте idxmax , чтобы получить первый экземпляр true для каждого столбца:

 m.idxmax()
 
 A    2
B    1
C    0
dtype: int64
 

Затем передайте еще раз, чтобы найти, где находится значение True и максимальный индекс для столбца:

 m amp; (m.index.values[:, None] == m.idxmax().values)
 
 [[False False  True]
 [False  True False]
 [ True False False]]
 

Наконец, вернитесь в фрейм данных:

 new_df = pd.DataFrame(
    m amp; (m.index.values[:, None] == m.idxmax().values),
    columns=df.columns,
    dtype=int
)
 
    A  B  C
0  0  0  1
1  0  1  0
2  1  0  0
 

Комментарии:

1. Спасибо. Шаг трансляции idmax-это то, чего мне не хватало,