Я думал, что, поскольку что-то в блоке try вызвало исключение, его содержимое пространства имен не может быть доверено, то есть ссылка на String 's' в блоке catch может вызвать бросок еще одного исключения.
Использование idxmax
df.loc[(df['color'] == 'blue').idxmax(),'number']
Out[698]: 4
Используйте head
- это вернет первую строку, если цвет существует, и пустую Series
в противном случае.
col = 'blue'
df.query('color == @col').head(1).loc[:, 'number']
1 4
Name: number, dtype: int64
В качестве альтернативы, чтобы получить один предмет, используйте obj.is_empty
:
u = df.query('color == @col').head(1)
if not u.is_empty:
print(u.at[u.index[0], 'number'])
# 4
Разница между head
и idxmax
для недопустимого цвета:
df.query('color == "blabla"').head(1).loc[:, 'number']
# Series([], Name: number, dtype: int64)
df.loc[(df['color'] == 'blabla').idxmax(),'number']
# 3
Использование iloc
с np.where
:
idx = next(iter(df['number'].iloc[np.where(df['color'].eq('blue'))]), -1) # 4
Обратите внимание, что это также обрабатывает случай, когда цвет не существует. Для сравнения df['color'].eq('orange').idxmax()
дает 0
, хотя 'orange'
не существует в ряду. Вышеуказанная логика даст -1
.
numba
Мне интересно, есть ли какой-либо более оптимальный подход, учитывая, что мне нужно только первое появление.
blockquote>Да! Более эффективное решение см. В . Эффективно вернуть индекс первого значения, удовлетворяющего условию в массиве . Numba позволяет эффективно выполнять итерацию по строкам. В этом случае вам нужно будет сначала разложить на множители строки , чтобы вы передавали числовые массивы только в Numba:
from numba import njit # factorize series, pd.factorize maintains order, # i.e. first item in values gives 0 index idx, values = pd.factorize(df['color']) idx_search = np.where(values == 'blue')[0][0] @njit def get_first_index_nb(A, k): for i in range(len(A)): if A[i] == k: return i return -1 res = df['number'].iat[get_first_index_nb(idx, 1)] # 4
Конечно, для одноразовых вычислений это неэффективно , Но для последовательных вычислений решение, скорее всего, будет фактором быстрее, чем решения, которые проверяют равенство по всей серии / массиву.